Import Geant4 11.4.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2025-06-26 09:17:29 +02:00
parent 20a218bbe1
commit a499fb82e9
1941 changed files with 203285 additions and 95593 deletions
+11 -3
View File
@@ -6,11 +6,19 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-03-14 I. Hrivnacova (analysis-V11-02-09)
## 2025-05-05 I. Hrivnacova (analysis-V11-03-03)
- New implementation of generic 'G4Analysis::GetHnType()'' and 'IsProfile()' functions
which does not rely on the histogram/profile name position in the long
type name provided via tools 's_class()'
## 2025-03-21 Ben Morgan (analysis-V11-03-02)
- Modernize g4tools macro-based for loops with range-based for
## 2025-03-14 I. Hrivnacova (analysis-V11-03-01)
- Removed false warnings about non-existing ntuple
and debug messages when filling inactivated ntuple
## 2025-01-09 Ben Morgan
## 2025-01-09 Ben Morgan (analysis-V11-03-00)
- Qualify use of `G4Accumulables` namespace to avoid clashes and order
dependence of inclusion of headers.
@@ -968,7 +976,7 @@ May 4, 2016 I. Hrivnacova (analysis-V10-02-02)
April 18, 2016 I. Hrivnacova (analysis-V10-02-01)
- Updated to g4tools 1.27.0 (Guy Barrand):
Fixed incompatibility with ROOT 5.x and 6.x formats reported in ROOT forum:
https://root.cern.ch/phpBB3/viewtopic.php?t=21315
https://root.cern/phpBB3/viewtopic.php?t=21315
December 8, 2015 I. Hrivnacova (analysis-V10-02-00)
- Fixed definition of /analysis/ntuple command directory
+1 -1
View File
@@ -679,7 +679,7 @@ May 4, 2016 I. Hrivnacova (analysis-V10-02-02)
April 18, 2016 I. Hrivnacova (analysis-V10-02-01)
- Updated to g4tools 1.27.0 (Guy Barrand):
Fixed incompatibility with ROOT 5.x and 6.x formats reported in ROOT forum:
https://root.cern.ch/phpBB3/viewtopic.php?t=21315
https://root.cern/phpBB3/viewtopic.php?t=21315
December 8, 2015 I. Hrivnacova (analysis-V10-02-00)
- Fixed definition of /analysis/ntuple command directory
+2 -6
View File
@@ -46,8 +46,7 @@ namespace {
void HD_style(tools::sg::plots& a_plots,float a_line_width) {
std::vector<tools::sg::plotter*> plotters;
a_plots.plotters(plotters);
tools_vforcit(tools::sg::plotter*,plotters,it) {
tools::sg::plotter* _plotter = *it;
for (auto* _plotter : plotters) {
_plotter->bins_style(0).line_width = a_line_width;
_plotter->inner_frame_style().line_width = a_line_width;
_plotter->grid_style().line_width = a_line_width;
@@ -105,9 +104,7 @@ void regions_style(tools::sg::plots& a_plots,float a_plotter_scale = 1) {
std::vector<tools::sg::plotter*> plotters;
a_plots.plotters(plotters);
tools_vforcit(tools::sg::plotter*,plotters,it) {
tools::sg::plotter* _plotter = *it;
for (auto* _plotter : plotters) {
_plotter->left_margin = _plotter->left_margin * wfac;
_plotter->right_margin = _plotter->right_margin * wfac;
_plotter->bottom_margin = _plotter->bottom_margin * hfac;
@@ -121,7 +118,6 @@ void regions_style(tools::sg::plots& a_plots,float a_plotter_scale = 1) {
_plotter->x_axis().label_height = _plotter->x_axis().label_height * hfac * label_cooking;
_plotter->y_axis().label_height = _plotter->y_axis().label_height * hfac * label_cooking;
}
}
@@ -93,7 +93,16 @@ G4String GetHnType()
G4String hnTypeLong = HT::s_class();
// tools::histo::h1d -> h1 etc.
return hnTypeLong.substr(14, 2);
std::size_t lastColon = hnTypeLong.rfind(":");
if (lastColon != G4String::npos && lastColon + 1 < hnTypeLong.length()) {
G4String potentialType = hnTypeLong.substr(lastColon + 1);
if (potentialType.length() >= 2 &&
(potentialType.substr(0, 1) == "h" || potentialType.substr(0, 1) == "p")) {
return potentialType.substr(0, 2);
}
}
G4cerr << "Warning: Could not extract short hnType for " << hnTypeLong << G4endl;
return "";
}
template <typename HT>
@@ -101,9 +110,9 @@ G4bool IsProfile()
{
// tools::histo::h1d etc.
G4String hnTypeLong = HT::s_class();
// tools::histo::h1d -> h1 etc.
return hnTypeLong[14] == 'p';
std::size_t length = hnTypeLong.length();
return (length >= 3 && hnTypeLong.substr(length - 3) == "p1d") ||
(length >= 3 && hnTypeLong.substr(length - 3) == "p2d");
}
// String conversion
@@ -179,8 +179,8 @@ void G4RootPNtupleManager::CreateNtupleFromMain(
}
else {
std::vector<tools::uint32> basketSizes;
tools_vforcit(tools::wroot::branch*, ntupleDescription->GetMainBranches(), it) {
basketSizes.push_back((*it)->basket_size());
for (const auto* branch : ntupleDescription->GetMainBranches()) {
basketSizes.push_back(branch->basket_size());
}
auto basketEntries = fMainNtupleManager->GetBasketEntries();
+1 -1
View File
@@ -6,7 +6,7 @@ be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-02-13 Gabriele Cosmo (event-V11-02-10)
## 2025-02-13 Gabriele Cosmo (event-V11-03-00)
- Fixed cut&paste error in G4StackManager::TransferStackedTracks(..),
reported by Coverity.
+1 -1
View File
@@ -6,7 +6,7 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-02-04 Gabriele Cosmo (clhep-V11-02-00)
## 2025-02-04 Gabriele Cosmo (clhep-V11-03-00)
- Properly export static symbols in RandFlat for DLL build support on Windows.
## 2023-10-13 Gabriele Cosmo (clhep-V11-01-03)
+33 -1
View File
@@ -6,7 +6,39 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-04-07 Gabriele Cosmo (g4tools-V11-02-06)
## 2025-06-17 Guy Barrand (g4tools-V11-03-04)
- toolx/Qt/glarea: bug: Qt5: in mouseMoveEvent() for Qt5, correct a bad cut/paste when creating the
mouse_move_event (instead of "x,shift,control,y" have "x,y,shift,control").
- tools/version: pass to 6.5.1
## 2025-06-16 Guy Barrand (g4tools-V11-03-03)
- tools/sg/event: have a new position_modifiers class to handle the shift, control key modifiers and mouse position.
It is inherited by mouse_[down,up,move]_event and the wheel_rotate_event class.
- toolx/Qt,Windows/glarea,pixwin, toolx/Xt/[sg,zb]_viewer, toolx/X11/zb_viewer: handle the shift and control
modifiers in the mouse_[down,up,move]_event and wheel_rotation_event.
- tools/version: pass to 6.5.0
## 2025-06-06 Guy Barrand (g4tools-V11-03-02)
- tools/rroot/ntuple: fix bugzilla 2657: in initialize(), line 708, pass the message from
"warning" to "error" and "return false" if the name of a booking column is not found in the file.
- tools/rcsv_ntuple: initialize(read with binding): check if given binding variables names are in the read from file column names.
If not, return an error; then have the same behaviour than for root ntuple reading with binding.
- tools/hdf5/ntuple: initialize(read with binding): check if given binding variables names are in the read from file column names.
If not, return an error; then have the same behaviour than for root ntuple reading with binding.
- tools/version: pass to 6.4.1.
## 2025-06-02 Guy Barrand (g4tools-V11-03-01)
- toolx/Qt,Windows,Xt,X11/sg_viewer and zb_viewer: implement window_size, and render_area_size methods.
(These may return different sizes, for example with Qt/OpenGL on Mac and Windows).
- tools/offscreen/sg_viewer: implement window_size, and render_area_size methods.
- tools/sg/event: handle the mouse position in the wheel_rotate_event class.
- toolx/Qt/glarea,pixwin: set the mouse position in the wheel_rotation_event.
- toolx/Windows/glarea,pixwin: set the mouse position in the wheel_rotation_event.
- toolx/Xt/sg_viewer: set the mouse position in the wheel_rotation_event.
- toolx/X11/zb_viewer: set the mouse position in the wheel_rotation_event.
- tools/version: pass to 6.4.0
## 2025-04-07 Gabriele Cosmo (g4tools-V11-03-00)
- Fixed compilation errors on Windows in glarea header, triggered when enabling
GL WIN32 support, as reported in problem report #2599.
+32
View File
@@ -1,3 +1,35 @@
6.5.1:
- toolx/Qt/glarea: bug: Qt5: in mouseMoveEvent() for Qt5, correct a bad cut/paste when creating the
mouse_move_event (instead of "x,shift,control,y" have "x,y,shift,control").
- tools/version: pass to 6.5.1
6.5.0:
- tools/sg/event: have a new position_modifiers class to handle the shift, control key modifiers and mouse position.
It is inherited by mouse_[down,up,move]_event and the wheel_rotate_event class.
- toolx/Qt,Windows/glarea,pixwin, toolx/Xt/[sg,zb]_viewer, toolx/X11/zb_viewer: handle the shift and control
modifiers in the mouse_[down,up,move]_event and wheel_rotation_event.
- tools/version: pass to 6.5.0
6.4.1:
- tools/rroot/ntuple: fix Geant4 bugzilla 2657: in initialize(), line 708, pass the message from
"warning" to "error" and "return false" if the name of a booking column is not found in the file.
- tools/rcsv_ntuple: initialize(read with binding): check if given binding variables names are in the read from file column names.
If not, return an error; then have the same behaviour than for root ntuple reading with binding.
- tools/hdf5/ntuple: initialize(read with binding): check if given binding variables names are in the read from file column names.
If not, return an error; then have the same behaviour than for root ntuple reading with binding.
- tools/version: pass to 6.4.1.
6.4.0:
- toolx/Qt,Windows,Xt,X11/sg_viewer and zb_viewer: implement window_size, and render_area_size methods.
(These may return different sizes, for example with Qt/OpenGL on Mac and Windows).
- tools/offscreen/sg_viewer: implement window_size, and render_area_size methods.
- tools/sg/event: handle the mouse position in the wheel_rotate_event class.
- toolx/Qt/glarea,pixwin: set the mouse position in the wheel_rotation_event.
- toolx/Windows/glarea,pixwin: set the mouse position in the wheel_rotation_event.
- toolx/Xt/sg_viewer: set the mouse position in the wheel_rotation_event.
- toolx/X11/zb_viewer: set the mouse position in the wheel_rotation_event.
- tools/version: pass to 6.4.0
6.3.3:
- wroot/file: in compress_buffer(): to fix bugzilla-2625: arrange to have a greater
output buffer size when using deflate(), and check at end, that in case of some
@@ -75,6 +75,16 @@ public:
m_session.to_render(this);
}
bool window_size(unsigned int& a_w,unsigned int& a_h) {
a_w = parent::width();
a_h = parent::height();
return true;
}
void render_area_size(unsigned int& a_w,unsigned int& a_h) {
a_w = parent::width();
a_h = parent::height();
}
void set_device_interactor(sg::device_interactor*) {}
public:
+19
View File
@@ -477,6 +477,7 @@ public:
}
}
}
size_t num = m_cols.size();
if(!num) {
a_out << "tools::rcsv::ntuple::initialize :"
@@ -664,9 +665,27 @@ public:
a_out << "tools::rcsv::ntuple::initialize(booking) :"
<< " zero columns."
<< std::endl;
m_sep = 0;
m_sz = 0;
m_rows = -1;
m_hippo = false;
return false;
}
{tools_vforcit(column_binding,a_bd.columns(),it) {
if(!find_named<read::icol>(m_cols,(*it).name())) {
a_out << "tools::rcsv::ntuple::initialize :"
<< " error : for column binding with name " << sout((*it).name()) << ", no ntuple column found."
<< std::endl;
safe_clear<read::icol>(m_cols);
m_sep = 0;
m_sz = 0;
m_rows = -1;
m_hippo = false;
return false;
}
}}
//a_out << "tools::rroot::ntuple::initialize :"
// << " number of columns " << num << "."
// << std::endl;
+3 -1
View File
@@ -705,8 +705,10 @@ public:
{tools_vforcit(column_binding,a_bd.columns(),it) {
if(!find_named<read::icol>(m_cols,(*it).name())) {
a_out << "tools::rroot::ntuple::initialize :"
<< " warning : for column binding with name " << sout((*it).name()) << ", no ntuple column found."
<< " error : for column binding with name " << sout((*it).name()) << ", no ntuple column found."
<< std::endl;
safe_clear<read::icol>(m_cols);
return false;
}
}}
+68 -51
View File
@@ -104,8 +104,44 @@ protected:
unsigned int m_h;
};
class mouse_down_event : public event {
class position_modifiers {
public:
position_modifiers(int a_x,int a_y,bool a_shift_modifier,bool a_control_modifier)
:m_x(a_x)
,m_y(a_y)
,m_shift_modifier(a_shift_modifier)
,m_control_modifier(a_control_modifier)
{}
virtual ~position_modifiers(){}
public:
position_modifiers(const position_modifiers& a_from)
:m_x(a_from.m_x)
,m_y(a_from.m_y)
,m_shift_modifier(a_from.m_shift_modifier)
,m_control_modifier(a_from.m_control_modifier)
{}
position_modifiers& operator=(const position_modifiers& a_from){
m_x = a_from.m_x;
m_y = a_from.m_y;
m_shift_modifier = a_from.m_shift_modifier;
m_control_modifier = a_from.m_control_modifier;
return *this;
}
public:
int x() const {return m_x;}
int y() const {return m_y;}
bool shift_modifier() const {return m_shift_modifier;}
bool control_modifier() const {return m_control_modifier;}
protected:
int m_x;
int m_y;
bool m_shift_modifier;
bool m_control_modifier;
};
class mouse_down_event : public event, public position_modifiers {
typedef event parent;
typedef position_modifiers parent_pos_mod;
public:
#ifdef TOOLS_SG_EVENT_ID_CAST
static cid id_class() {return parent::id_class()+2;}
@@ -122,33 +158,25 @@ public:
#endif
virtual event* copy() const {return new mouse_down_event(*this);}
public:
mouse_down_event(int a_x,int a_y) //signed because of wall.
:m_x(a_x)
,m_y(a_y)
mouse_down_event(int a_x,int a_y,bool a_shift_modifier,bool a_control_modifier)
:parent_pos_mod(a_x,a_y,a_shift_modifier,a_control_modifier)
{}
virtual ~mouse_down_event(){}
public:
mouse_down_event(const mouse_down_event& a_from)
:event(a_from)
,m_x(a_from.m_x)
,m_y(a_from.m_y)
:parent(a_from)
,parent_pos_mod(a_from)
{}
mouse_down_event& operator=(const mouse_down_event& a_from){
event::operator=(a_from);
m_x = a_from.m_x;
m_y = a_from.m_y;
parent::operator=(a_from);
parent_pos_mod::operator=(a_from);
return *this;
}
public:
int x() const {return m_x;}
int y() const {return m_y;}
protected:
int m_x;
int m_y;
};
class mouse_up_event : public event {
class mouse_up_event : public event, public position_modifiers {
typedef event parent;
typedef position_modifiers parent_pos_mod;
public:
#ifdef TOOLS_SG_EVENT_ID_CAST
static cid id_class() {return parent::id_class()+3;}
@@ -165,33 +193,25 @@ public:
#endif
virtual event* copy() const {return new mouse_up_event(*this);}
public:
mouse_up_event(int a_x,int a_y) //signed because of wall.
:m_x(a_x)
,m_y(a_y)
mouse_up_event(int a_x,int a_y,bool a_shift_modifier,bool a_control_modifier)
:parent_pos_mod(a_x,a_y,a_shift_modifier,a_control_modifier)
{}
virtual ~mouse_up_event(){}
public:
mouse_up_event(const mouse_up_event& a_from)
:event(a_from)
,m_x(a_from.m_x)
,m_y(a_from.m_y)
:parent(a_from)
,parent_pos_mod(a_from)
{}
mouse_up_event& operator=(const mouse_up_event& a_from){
event::operator=(a_from);
m_x = a_from.m_x;
m_y = a_from.m_y;
parent::operator=(a_from);
parent_pos_mod::operator=(a_from);
return *this;
}
public:
int x() const {return m_x;}
int y() const {return m_y;}
protected:
int m_x;
int m_y;
};
class mouse_move_event : public event {
class mouse_move_event : public event, public position_modifiers {
typedef event parent;
typedef position_modifiers parent_pos_mod;
public:
#ifdef TOOLS_SG_EVENT_ID_CAST
static cid id_class() {return parent::id_class()+4;}
@@ -208,11 +228,10 @@ public:
#endif
virtual event* copy() const {return new mouse_move_event(*this);}
public:
mouse_move_event(int a_x,int a_y, //signed because of wall.
mouse_move_event(int a_x,int a_y,bool a_shift_modifier,bool a_control_modifier,
int a_ox,int a_oy,
bool a_touch) //for sliders.
:m_x(a_x)
,m_y(a_y)
:parent_pos_mod(a_x,a_y,a_shift_modifier,a_control_modifier)
,m_ox(a_ox)
,m_oy(a_oy)
,m_touch(a_touch)
@@ -220,17 +239,15 @@ public:
virtual ~mouse_move_event(){}
public:
mouse_move_event(const mouse_move_event& a_from)
:event(a_from)
,m_x(a_from.m_x)
,m_y(a_from.m_y)
:parent(a_from)
,parent_pos_mod(a_from)
,m_ox(a_from.m_ox)
,m_oy(a_from.m_oy)
,m_touch(a_from.m_touch)
{}
mouse_move_event& operator=(const mouse_move_event& a_from){
event::operator=(a_from);
m_x = a_from.m_x;
m_y = a_from.m_y;
parent::operator=(a_from);
parent_pos_mod::operator=(a_from);
m_ox = a_from.m_ox;
m_oy = a_from.m_oy;
@@ -239,14 +256,10 @@ public:
return *this;
}
public:
int x() const {return m_x;}
int y() const {return m_y;}
int ox() const {return m_ox;}
int oy() const {return m_oy;}
bool is_touch() const {return m_touch;}
protected:
int m_x;
int m_y;
int m_ox;
int m_oy; //+ = up.
// etc :
@@ -385,8 +398,9 @@ protected:
key_code m_key;
};
class wheel_rotate_event : public event {
class wheel_rotate_event : public event, public position_modifiers {
typedef event parent;
typedef position_modifiers parent_pos_mod;
public:
#ifdef TOOLS_SG_EVENT_ID_CAST
static cid id_class() {return parent::id_class()+8;}
@@ -403,17 +417,20 @@ public:
#endif
virtual event* copy() const {return new wheel_rotate_event(*this);}
public:
wheel_rotate_event(int a_angle)
:m_angle(a_angle)
wheel_rotate_event(int a_angle,int a_x,int a_y,bool a_shift_modifier,bool a_control_modifier)
:parent_pos_mod(a_x,a_y,a_shift_modifier,a_control_modifier)
,m_angle(a_angle)
{}
virtual ~wheel_rotate_event(){}
public:
wheel_rotate_event(const wheel_rotate_event& a_from)
:event(a_from)
:parent(a_from)
,parent_pos_mod(a_from)
,m_angle(a_from.m_angle)
{}
wheel_rotate_event& operator=(const wheel_rotate_event& a_from){
event::operator=(a_from);
parent::operator=(a_from);
parent_pos_mod::operator=(a_from);
m_angle = a_from.m_angle;
return *this;
}
+5 -5
View File
@@ -5,13 +5,13 @@
#define tools_version
#define TOOLS_MAJOR_VERSION 6
#define TOOLS_MINOR_VERSION 3
#define TOOLS_PATCH_VERSION 3
#define TOOLS_VERSION "6.3.3"
#define TOOLS_VERSION_VRP "v6r3p3"
#define TOOLS_MINOR_VERSION 5
#define TOOLS_PATCH_VERSION 1
#define TOOLS_VERSION "6.5.1"
#define TOOLS_VERSION_VRP "v6r5p1"
namespace tools {
inline unsigned int version() {return 60303;}
inline unsigned int version() {return 60501;}
}
#endif
+27 -7
View File
@@ -60,34 +60,54 @@ public:
}
virtual void mousePressEvent(QMouseEvent* a_event) {
if(!m_interactor) return;
bool shift_modifier = a_event->modifiers() & ::Qt::ShiftModifier;
bool control_modifier = a_event->modifiers() & ::Qt::ControlModifier;
#if QT_VERSION < 0x060000
tools::sg::mouse_down_event _event(a_event->x(),a_event->y());
tools::sg::mouse_down_event _event(a_event->x(),a_event->y(),shift_modifier,control_modifier);
#else
tools::sg::mouse_down_event _event(a_event->position().x(),a_event->position().y());
tools::sg::mouse_down_event _event(a_event->position().x(),a_event->position().y(),shift_modifier,control_modifier);
#endif
m_interactor->mouse_press(_event);
}
virtual void mouseReleaseEvent(QMouseEvent* a_event) {
if(!m_interactor) return;
bool shift_modifier = a_event->modifiers() & ::Qt::ShiftModifier;
bool control_modifier = a_event->modifiers() & ::Qt::ControlModifier;
#if QT_VERSION < 0x060000
tools::sg::mouse_up_event _event(a_event->x(),a_event->y());
tools::sg::mouse_up_event _event(a_event->x(),a_event->y(),shift_modifier,control_modifier);
#else
tools::sg::mouse_up_event _event(a_event->position().x(),a_event->position().y());
tools::sg::mouse_up_event _event(a_event->position().x(),a_event->position().y(),shift_modifier,control_modifier);
#endif
m_interactor->mouse_release(_event);
}
virtual void mouseMoveEvent(QMouseEvent* a_event) {
if(!m_interactor) return;
bool shift_modifier = a_event->modifiers() & ::Qt::ShiftModifier;
bool control_modifier = a_event->modifiers() & ::Qt::ControlModifier;
#if QT_VERSION < 0x060000
tools::sg::mouse_move_event _event(a_event->x(),a_event->y(),0,0,false);
tools::sg::mouse_move_event _event(a_event->x(),a_event->y(),shift_modifier,control_modifier,0,0,false);
#else
tools::sg::mouse_move_event _event(a_event->position().x(),a_event->position().y(),0,0,false);
tools::sg::mouse_move_event _event(a_event->position().x(),a_event->position().y(),shift_modifier,control_modifier,0,0,false);
#endif
m_interactor->mouse_move(_event);
}
virtual void wheelEvent(QWheelEvent* a_event) {
if(!m_interactor) return;
tools::sg::wheel_rotate_event _event(a_event->angleDelta().y());
bool shift_modifier = a_event->modifiers() & ::Qt::ShiftModifier;
bool control_modifier = a_event->modifiers() & ::Qt::ControlModifier;
#if QT_VERSION < 0x050f00 //5.15.00
tools::sg::wheel_rotate_event _event(a_event->angleDelta().y(),a_event->x(),a_event->y(),shift_modifier,control_modifier);
#else
tools::sg::wheel_rotate_event _event(a_event->angleDelta().y(),a_event->position().x(),a_event->position().y(),shift_modifier,control_modifier);
#endif
m_interactor->wheel_rotate(_event);
}
+27 -7
View File
@@ -59,28 +59,40 @@ public:
}
virtual void mousePressEvent(QMouseEvent* a_event) {
if(!m_interactor) return;
bool shift_modifier = a_event->modifiers() & ::Qt::ShiftModifier;
bool control_modifier = a_event->modifiers() & ::Qt::ControlModifier;
#if QT_VERSION < 0x060000
tools::sg::mouse_down_event _event(a_event->x(),a_event->y());
tools::sg::mouse_down_event _event(a_event->x(),a_event->y(),shift_modifier,control_modifier);
#else
tools::sg::mouse_down_event _event(a_event->position().x(),a_event->position().y());
tools::sg::mouse_down_event _event(a_event->position().x(),a_event->position().y(),shift_modifier,control_modifier);
#endif
m_interactor->mouse_press(_event);
}
virtual void mouseReleaseEvent(QMouseEvent* a_event) {
if(!m_interactor) return;
bool shift_modifier = a_event->modifiers() & ::Qt::ShiftModifier;
bool control_modifier = a_event->modifiers() & ::Qt::ControlModifier;
#if QT_VERSION < 0x060000
tools::sg::mouse_up_event _event(a_event->x(),a_event->y());
tools::sg::mouse_up_event _event(a_event->x(),a_event->y(),shift_modifier,control_modifier);
#else
tools::sg::mouse_up_event _event(a_event->position().x(),a_event->position().y());
tools::sg::mouse_up_event _event(a_event->position().x(),a_event->position().y(),shift_modifier,control_modifier);
#endif
m_interactor->mouse_release(_event);
}
virtual void mouseMoveEvent(QMouseEvent* a_event) {
if(!m_interactor) return;
bool shift_modifier = a_event->modifiers() & ::Qt::ShiftModifier;
bool control_modifier = a_event->modifiers() & ::Qt::ControlModifier;
#if QT_VERSION < 0x060000
tools::sg::mouse_move_event _event(a_event->x(),a_event->y(),0,0,false);
tools::sg::mouse_move_event _event(a_event->x(),a_event->y(),shift_modifier,control_modifier,0,0,false);
#else
tools::sg::mouse_move_event _event(a_event->position().x(),a_event->position().y(),0,0,false);
tools::sg::mouse_move_event _event(a_event->position().x(),a_event->position().y(),shift_modifier,control_modifier,0,0,false);
#endif
m_interactor->mouse_move(_event);
}
@@ -91,7 +103,15 @@ public:
//}
virtual void wheelEvent(QWheelEvent* a_event) {
if(!m_interactor) return;
tools::sg::wheel_rotate_event _event(a_event->angleDelta().y());
bool shift_modifier = a_event->modifiers() & ::Qt::ShiftModifier;
bool control_modifier = a_event->modifiers() & ::Qt::ControlModifier;
#if QT_VERSION < 0x050f00 //5.15.00
tools::sg::wheel_rotate_event _event(a_event->angleDelta().y(),a_event->x(),a_event->y(),shift_modifier,control_modifier);
#else
tools::sg::wheel_rotate_event _event(a_event->angleDelta().y(),a_event->position().x(),a_event->position().y(),shift_modifier,control_modifier);
#endif
m_interactor->wheel_rotate(_event);
}
+12
View File
@@ -76,6 +76,18 @@ public:
if(!m_glarea) return;
m_glarea->update();
}
bool window_size(unsigned int& a_w,unsigned int& a_h) {
if(!m_glarea) {a_w = 0;a_h = 0;return false;}
a_w = (unsigned int)m_glarea->width();
a_h = (unsigned int)m_glarea->height();
return true;
}
void render_area_size(unsigned int& a_w,unsigned int& a_h) {
a_w = parent::width();
a_h = parent::height();
}
public:
QWidget* shell() {return m_shell;}
void set_own_shell(bool a_value) {m_own_shell = a_value;}
+11
View File
@@ -80,6 +80,17 @@ public:
m_render_area->repaint(); //immediate.
}
bool window_size(unsigned int& a_w,unsigned int& a_h) {
if(!m_render_area) {a_w = 0;a_h = 0;return false;}
a_w = (unsigned int)m_render_area->width();
a_h = (unsigned int)m_render_area->height();
return true;
}
void render_area_size(unsigned int& a_w,unsigned int& a_h) {
a_w = parent::width();
a_h = parent::height();
}
void set_device_interactor(tools::sg::device_interactor* a_interactor) { //we do not have ownership.
if(!m_render_area) return;
m_render_area->set_device_interactor(a_interactor);
+21 -8
View File
@@ -74,7 +74,6 @@ public:
,m_interactor(0)
{
register_class();
// The WS_BORDER is needed. Else probleme of size at startup.
RECT rect;
::GetClientRect(m_parent,&rect);
//printf("debug : glarea : ca : %d %d\n",rect.right-rect.left,rect.bottom-rect.top);
@@ -248,7 +247,9 @@ protected:
glarea* _this = (glarea*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
if(_this) {
if(_this->m_interactor) {
tools::sg::mouse_down_event event(LOWORD(a_lparam),HIWORD(a_lparam));
bool shift_modifier = ::GetKeyState(VK_SHIFT) & 0x8000;
bool control_modifier = ::GetKeyState(VK_CONTROL) & 0x8000;
tools::sg::mouse_down_event event(LOWORD(a_lparam),HIWORD(a_lparam),shift_modifier,control_modifier);
_this->m_interactor->mouse_press(event);
} else {
RECT rect;
@@ -262,7 +263,9 @@ protected:
glarea* _this = (glarea*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
if(_this) {
if(_this->m_interactor) {
tools::sg::mouse_up_event event(LOWORD(a_lparam),HIWORD(a_lparam));
bool shift_modifier = ::GetKeyState(VK_SHIFT) & 0x8000;
bool control_modifier = ::GetKeyState(VK_CONTROL) & 0x8000;
tools::sg::mouse_up_event event(LOWORD(a_lparam),HIWORD(a_lparam),shift_modifier,control_modifier);
_this->m_interactor->mouse_release(event);
} else {
RECT rect;
@@ -275,12 +278,16 @@ protected:
case WM_MOUSEMOVE:{
glarea* _this = (glarea*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
if(_this) {
WPARAM state = a_wparam;
bool ldown = ((state & MK_LBUTTON)==MK_LBUTTON)?true:false;
if(_this->m_interactor) {
tools::sg::mouse_move_event event(LOWORD(a_lparam),HIWORD(a_lparam),0,0,false);
_this->m_interactor->mouse_move(event);
if(ldown) {
bool shift_modifier = ::GetKeyState(VK_SHIFT) & 0x8000;
bool control_modifier = ::GetKeyState(VK_CONTROL) & 0x8000;
tools::sg::mouse_move_event event(LOWORD(a_lparam),HIWORD(a_lparam),shift_modifier,control_modifier,0,0,false);
_this->m_interactor->mouse_move(event);
}
} else {
WPARAM state = a_wparam;
bool ldown = ((state & MK_LBUTTON)==MK_LBUTTON)?true:false;
RECT rect;
::GetClientRect(a_hwnd,&rect);
unsigned int h = rect.bottom-rect.top;
@@ -294,7 +301,13 @@ protected:
glarea* _this = (glarea*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
if(_this) {
if(_this->m_interactor) {
tools::sg::wheel_rotate_event event(GET_WHEEL_DELTA_WPARAM(a_wparam));
bool shift_modifier = ::GetKeyState(VK_SHIFT) & 0x8000;
bool control_modifier = ::GetKeyState(VK_CONTROL) & 0x8000;
POINT p;
p.x = LOWORD(a_lparam);
p.y = HIWORD(a_lparam);
if(!::ScreenToClient(a_hwnd,&p)) {}
tools::sg::wheel_rotate_event event(GET_WHEEL_DELTA_WPARAM(a_wparam),int(p.x),int(p.y),shift_modifier,control_modifier);
_this->m_interactor->wheel_rotate(event);
}
}
+21 -7
View File
@@ -195,7 +195,9 @@ protected:
pixwin* _this = (pixwin*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
if(_this) {
if(_this->m_interactor) {
tools::sg::mouse_down_event event(LOWORD(a_lparam),HIWORD(a_lparam));
bool shift_modifier = ::GetKeyState(VK_SHIFT) & 0x8000;
bool control_modifier = ::GetKeyState(VK_CONTROL) & 0x8000;
tools::sg::mouse_down_event event(LOWORD(a_lparam),HIWORD(a_lparam),shift_modifier,control_modifier);
_this->m_interactor->mouse_press(event);
} else {
RECT rect;
@@ -209,7 +211,9 @@ protected:
pixwin* _this = (pixwin*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
if(_this) {
if(_this->m_interactor) {
tools::sg::mouse_up_event event(LOWORD(a_lparam),HIWORD(a_lparam));
bool shift_modifier = ::GetKeyState(VK_SHIFT) & 0x8000;
bool control_modifier = ::GetKeyState(VK_CONTROL) & 0x8000;
tools::sg::mouse_up_event event(LOWORD(a_lparam),HIWORD(a_lparam),shift_modifier,control_modifier);
_this->m_interactor->mouse_release(event);
} else {
RECT rect;
@@ -222,12 +226,16 @@ protected:
case WM_MOUSEMOVE:{
pixwin* _this = (pixwin*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
if(_this) {
WPARAM state = a_wparam;
bool ldown = ((state & MK_LBUTTON)==MK_LBUTTON)?true:false;
if(_this->m_interactor) {
tools::sg::mouse_move_event event(LOWORD(a_lparam),HIWORD(a_lparam),0,0,false);
_this->m_interactor->mouse_move(event);
if(ldown) {
bool shift_modifier = ::GetKeyState(VK_SHIFT) & 0x8000;
bool control_modifier = ::GetKeyState(VK_CONTROL) & 0x8000;
tools::sg::mouse_move_event event(LOWORD(a_lparam),HIWORD(a_lparam),shift_modifier,control_modifier,0,0,false);
_this->m_interactor->mouse_move(event);
}
} else {
WPARAM state = a_wparam;
bool ldown = ((state & MK_LBUTTON)==MK_LBUTTON)?true:false;
RECT rect;
::GetClientRect(a_hwnd,&rect);
unsigned int h = rect.bottom-rect.top;
@@ -241,7 +249,13 @@ protected:
pixwin* _this = (pixwin*)::GetWindowLongPtr(a_hwnd,GWLP_USERDATA);
if(_this) {
if(_this->m_interactor) {
tools::sg::wheel_rotate_event event(GET_WHEEL_DELTA_WPARAM(a_wparam));
bool shift_modifier = ::GetKeyState(VK_SHIFT) & 0x8000;
bool control_modifier = ::GetKeyState(VK_CONTROL) & 0x8000;
POINT p;
p.x = LOWORD(a_lparam);
p.y = HIWORD(a_lparam);
if(!::ScreenToClient(a_hwnd,&p)) {}
tools::sg::wheel_rotate_event event(GET_WHEEL_DELTA_WPARAM(a_wparam),int(p.x),int(p.y),shift_modifier,control_modifier);
_this->m_interactor->wheel_rotate(event);
}
}
@@ -58,6 +58,18 @@ public:
void win_render() {m_glarea.wm_paint();}
bool window_size(unsigned int& a_w,unsigned int& a_h) {
if(!m_glarea.hwnd()) {a_w = 0;a_h = 0;return false;}
RECT wrect;
::GetWindowRect(m_glarea.hwnd(),&wrect);
a_w = wrect.right-wrect.left;
a_h = wrect.bottom-wrect.top;
return true;
}
void render_area_size(unsigned int& a_w,unsigned int& a_h) {
a_w = parent_viewer::width();
a_h = parent_viewer::height();
}
public:
void set_device_interactor(tools::sg::device_interactor* a_interactor) { //we do not have ownership.
@@ -78,6 +78,20 @@ public:
}
void win_render() {parent_render_area::wm_paint();}
bool window_size(unsigned int& a_w,unsigned int& a_h) {
if(!parent_render_area::m_hwnd) {a_w = 0;a_h = 0;return false;}
RECT wrect;
::GetWindowRect(parent_render_area::m_hwnd,&wrect);
a_w = wrect.right-wrect.left;
a_h = wrect.bottom-wrect.top;
return true;
}
void render_area_size(unsigned int& a_w,unsigned int& a_h) {
a_w = parent_viewer::width();
a_h = parent_viewer::height();
}
void set_device_interactor(tools::sg::device_interactor* a_interactor) { //we do not have ownership.
parent_render_area::set_device_interactor(a_interactor);
}
+13
View File
@@ -100,6 +100,19 @@ public:
}
}
bool window_size(unsigned int& a_w,unsigned int& a_h) {
if(!m_win) {a_w = 0;a_h = 0;return false;}
int width,height;
if(!m_session.window_size(m_win,width,height)) {a_w = 0;a_h = 0;return false;}
a_w = (unsigned int)width;
a_h = (unsigned int)height;
return true;
}
void render_area_size(unsigned int& a_w,unsigned int& a_h) {
a_w = parent::width();
a_h = parent::height();
}
public:
void set_device_interactor(tools::sg::device_interactor*) {}
protected:
+20 -5
View File
@@ -24,30 +24,32 @@ private:
public:
virtual bool dispatch(XEvent& a_event) {
if(parent::dispatch(a_event)) return true;
bool shift_modifier = a_event.xkey.state & ShiftMask;
bool control_modifier = a_event.xkey.state & ControlMask;
if(a_event.type==ButtonPress && a_event.xbutton.button==1) {
if(!m_viewer.device_interactor()) return false;
tools::sg::mouse_down_event event(a_event.xbutton.x,a_event.xbutton.y);
tools::sg::mouse_down_event event(a_event.xbutton.x,a_event.xbutton.y,shift_modifier,control_modifier);
m_viewer.device_interactor()->mouse_press(event);
return true;
} else if(a_event.type==ButtonRelease && a_event.xbutton.button==1) {
if(!m_viewer.device_interactor()) return false;
tools::sg::mouse_up_event event(a_event.xbutton.x,a_event.xbutton.y);
tools::sg::mouse_up_event event(a_event.xbutton.x,a_event.xbutton.y,shift_modifier,control_modifier);
m_viewer.device_interactor()->mouse_release(event);
return true;
} else if(a_event.type==MotionNotify) {
if(!m_viewer.device_interactor()) return false;
if((a_event.xmotion.state & Button1MotionMask)==Button1MotionMask) {
tools::sg::mouse_move_event event(a_event.xmotion.x,a_event.xmotion.y,0,0,false);
tools::sg::mouse_move_event event(a_event.xmotion.x,a_event.xmotion.y,shift_modifier,control_modifier,0,0,false);
m_viewer.device_interactor()->mouse_move(event);
}
} else if((a_event.type==ButtonPress)&&(a_event.xbutton.button==4)) { // mouse scrollwheel down :
if(!m_viewer.device_interactor()) return false;
tools::sg::wheel_rotate_event event(8); //8=cooking.
tools::sg::wheel_rotate_event event(8,a_event.xbutton.x,a_event.xbutton.y,shift_modifier,control_modifier); //8=cooking.
m_viewer.device_interactor()->wheel_rotate(event);
return true;
} else if((a_event.type==ButtonPress)&&(a_event.xbutton.button==5)) { // mouse scrollwheel up :
if(!m_viewer.device_interactor()) return false;
tools::sg::wheel_rotate_event event(-8); //8=cooking.
tools::sg::wheel_rotate_event event(-8,a_event.xbutton.x,a_event.xbutton.y,shift_modifier,control_modifier); //8=cooking.
m_viewer.device_interactor()->wheel_rotate(event);
return true;
}
@@ -135,6 +137,19 @@ public:
m_out_buffer.clear();
}
bool window_size(unsigned int& a_w,unsigned int& a_h) {
if(!m_win) {a_w = 0;a_h = 0;return false;}
int width,height;
if(!m_session.window_size(m_win,width,height)) {a_w = 0;a_h = 0;return false;}
a_w = (unsigned int)width;
a_h = (unsigned int)height;
return true;
}
void render_area_size(unsigned int& a_w,unsigned int& a_h) {
a_w = parent::width();
a_h = parent::height();
}
void set_device_interactor(tools::sg::device_interactor* a_interactor) {m_interactor = a_interactor;}
public:
tools::sg::device_interactor* device_interactor() {return m_interactor;}
+22 -5
View File
@@ -108,6 +108,17 @@ public:
if(m_glarea) OpenGLArea::paint(m_glarea);
}
bool window_size(unsigned int& a_w,unsigned int& a_h) {
if(!m_glarea) {a_w = 0;a_h = 0;return false;}
a_w = (unsigned int)m_glarea->core.width;
a_h = (unsigned int)m_glarea->core.height;
return true;
}
void render_area_size(unsigned int& a_w,unsigned int& a_h) {
a_w = parent::width();
a_h = parent::height();
}
public:
void set_device_interactor(tools::sg::device_interactor* a_interactor) {m_interactor = a_interactor;} //we do not have ownership.
protected:
@@ -138,23 +149,29 @@ protected:
_this->m_interactor->key_release(event);
}return;
case ButtonPress:{
bool shift_modifier = xevent->xkey.state & ShiftMask;
bool control_modifier = xevent->xkey.state & ControlMask;
if(xevent->xbutton.button==Button4) { //4=wheel down, or move down double touch on trackpad = zoom in.
tools::sg::wheel_rotate_event event(8); //8=cooking.
tools::sg::wheel_rotate_event event(8,xevent->xbutton.x,xevent->xbutton.y,shift_modifier,control_modifier); //8=cooking.
_this->m_interactor->wheel_rotate(event);
} else if(xevent->xbutton.button==Button5) { //5=wheel up, or move up double touch on trackpad = zoom out.
tools::sg::wheel_rotate_event event(-8); //8=cooking.
tools::sg::wheel_rotate_event event(-8,xevent->xbutton.x,xevent->xbutton.y,shift_modifier,control_modifier); //8=cooking.
_this->m_interactor->wheel_rotate(event);
} else {
tools::sg::mouse_down_event event(xevent->xbutton.x,xevent->xbutton.y);
tools::sg::mouse_down_event event(xevent->xbutton.x,xevent->xbutton.y,shift_modifier,control_modifier);
_this->m_interactor->mouse_press(event);
}
}return;
case ButtonRelease:{
tools::sg::mouse_up_event event(xevent->xbutton.x,xevent->xbutton.y);
bool shift_modifier = xevent->xkey.state & ShiftMask;
bool control_modifier = xevent->xkey.state & ControlMask;
tools::sg::mouse_up_event event(xevent->xbutton.x,xevent->xbutton.y,shift_modifier,control_modifier);
_this->m_interactor->mouse_release(event);
}return;
case MotionNotify:{
tools::sg::mouse_move_event event(xevent->xmotion.x,xevent->xmotion.y,0,0,false);
bool shift_modifier = xevent->xkey.state & ShiftMask;
bool control_modifier = xevent->xkey.state & ControlMask;
tools::sg::mouse_move_event event(xevent->xmotion.x,xevent->xmotion.y,shift_modifier,control_modifier,0,0,false);
_this->m_interactor->mouse_move(event);
}return;
default:return;}
+22 -5
View File
@@ -116,6 +116,17 @@ public:
if(m_image_area) ImageArea::paint(m_image_area);
}
bool window_size(unsigned int& a_w,unsigned int& a_h) {
if(!m_image_area) {a_w = 0;a_h = 0;return false;}
a_w = m_image_area->core.width;
a_h = m_image_area->core.height;
return true;
}
void render_area_size(unsigned int& a_w,unsigned int& a_h) {
a_w = parent::width();
a_h = parent::height();
}
void set_device_interactor(tools::sg::device_interactor* a_interactor) {m_interactor = a_interactor;} //we do not have ownership.
protected:
static void resize_cbk(Widget a_widget,XtPointer a_tag,XtPointer){
@@ -157,26 +168,32 @@ protected:
_this->m_interactor->key_release(event);
}return;
case ButtonPress:{
bool shift_modifier = xevent->xkey.state & ShiftMask;
bool control_modifier = xevent->xkey.state & ControlMask;
if(xevent->xbutton.button==Button4) { //4=wheel down, or move down double touch on trackpad = zoom in.
tools::sg::wheel_rotate_event event(8); //8=cooking.
tools::sg::wheel_rotate_event event(8,xevent->xbutton.x,xevent->xbutton.y,shift_modifier,control_modifier); //8=cooking.
_this->m_interactor->wheel_rotate(event);
} else if(xevent->xbutton.button==Button5) { //5=wheel up, or move up double touch on trackpad = zoom out.
tools::sg::wheel_rotate_event event(-8); //8=cooking.
tools::sg::wheel_rotate_event event(-8,xevent->xbutton.x,xevent->xbutton.y,shift_modifier,control_modifier); //8=cooking.
_this->m_interactor->wheel_rotate(event);
} else if(xevent->xbutton.button==Button1) {
tools::sg::mouse_down_event event(xevent->xbutton.x,xevent->xbutton.y);
tools::sg::mouse_down_event event(xevent->xbutton.x,xevent->xbutton.y,shift_modifier,control_modifier);
_this->m_interactor->mouse_press(event);
}
}return;
case ButtonRelease:{
if(xevent->xbutton.button==Button1) {
tools::sg::mouse_up_event event(xevent->xbutton.x,xevent->xbutton.y);
bool shift_modifier = xevent->xkey.state & ShiftMask;
bool control_modifier = xevent->xkey.state & ControlMask;
tools::sg::mouse_up_event event(xevent->xbutton.x,xevent->xbutton.y,shift_modifier,control_modifier);
_this->m_interactor->mouse_release(event);
}
}return;
case MotionNotify:{
if((xevent->xmotion.state & Button1MotionMask)==Button1MotionMask) {
tools::sg::mouse_move_event event(xevent->xmotion.x,xevent->xmotion.y,0,0,false);
bool shift_modifier = xevent->xkey.state & ShiftMask;
bool control_modifier = xevent->xkey.state & ControlMask;
tools::sg::mouse_move_event event(xevent->xmotion.x,xevent->xmotion.y,shift_modifier,control_modifier,0,0,false);
_this->m_interactor->mouse_move(event);
}
}return;
+19
View File
@@ -967,6 +967,25 @@ public:
}
#undef TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL
#undef TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL
size_t num = m_cols.size();
if(!num) {
a_out << "toolx::hdf5::ntuple::ntuple(read with binding) :"
<< " zero columns."
<< std::endl;
return false;
}
{tools_vforcit(tools::column_binding,a_bd.columns(),it) {
if(!tools::find_named<icol>(m_cols,(*it).name())) {
a_out << "toolx::hdf5::ntuple::ntuple(read with binding) :"
<< " error : for column binding with name " << tools::sout((*it).name()) << ", no ntuple column found."
<< std::endl;
tools::safe_clear<icol>(m_cols);
return false;
}
}}
return true;
}
-9
View File
@@ -73,11 +73,6 @@ configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/src/zconf.h.cmakein
# -----
# - Geant4 specific part to integrate
#
# Intel/Clang may warn about -Wdeprecated-non-prototype, but per https://github.com/madler/zlib/issues/633
# we suppress this warning if the compiler supports the flag
include(CheckCCompilerFlag)
check_c_compiler_flag("-Wno-deprecated-non-prototype" G4ZLIB_NEEDS_DNP)
# Headers listed under Sources are internal zlib headers
# Private headers are in src!
set(ZLIB_PUBLIC_HDRS
@@ -121,10 +116,6 @@ foreach(__g4zlib_target G4zlib G4zlib-static)
PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
)
if(G4ZLIB_NEEDS_DNP)
target_compile_options(${__g4zlib_target} PRIVATE "-Wno-deprecated-non-prototype")
endif()
endif()
endforeach()
+5 -2
View File
@@ -6,8 +6,11 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-04-01 Gabriele Cosmo (zlib-V11-02-00)
- Fix in zutil.h to remove redundant block on macOS and allow for porting
## 2025-05-02 Ben Morgan (zlib-V11-03-01)
- Import zlib 1.3.1 sources, retaining prior Geant4 patches.
## 2025-04-01 Gabriele Cosmo (zlib-V11-03-00)
- Fix in zutil.h to comment out redundant block on macOS and allow for porting
on macOS-15.4 and clang-17.0.0.
## 2023-06-15 Ben Morgan (zlib-V11-01-00)
+41 -10
View File
@@ -1,5 +1,5 @@
/* deflate.h -- internal compression state
* Copyright (C) 1995-2018 Jean-loup Gailly
* Copyright (C) 1995-2024 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -23,6 +23,10 @@
# define GZIP
#endif
/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at
the cost of a larger memory footprint */
/* #define LIT_MEM */
/* ===========================================================================
* Internal compression state.
*/
@@ -217,7 +221,14 @@ typedef struct internal_state {
/* Depth of each subtree used as tie breaker for trees of equal frequency
*/
#ifdef LIT_MEM
# define LIT_BUFS 5
ushf *d_buf; /* buffer for distances */
uchf *l_buf; /* buffer for literals/lengths */
#else
# define LIT_BUFS 4
uchf *sym_buf; /* buffer for distances and literals/lengths */
#endif
uInt lit_bufsize;
/* Size of match buffer for literals/lengths. There are 4 reasons for
@@ -239,7 +250,7 @@ typedef struct internal_state {
* - I can't count above 4
*/
uInt sym_next; /* running index in sym_buf */
uInt sym_next; /* running index in symbol buffer */
uInt sym_end; /* symbol table full when sym_next reaches this */
ulg opt_len; /* bit length of current block with optimal trees */
@@ -291,14 +302,14 @@ typedef struct internal_state {
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));
void ZLIB_INTERNAL _tr_init(deflate_state *s);
int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc);
void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf,
ulg stored_len, int last);
void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s);
void ZLIB_INTERNAL _tr_align(deflate_state *s);
void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf,
ulg stored_len, int last);
#define d_code(dist) \
((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
@@ -318,6 +329,25 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
extern const uch ZLIB_INTERNAL _dist_code[];
#endif
#ifdef LIT_MEM
# define _tr_tally_lit(s, c, flush) \
{ uch cc = (c); \
s->d_buf[s->sym_next] = 0; \
s->l_buf[s->sym_next++] = cc; \
s->dyn_ltree[cc].Freq++; \
flush = (s->sym_next == s->sym_end); \
}
# define _tr_tally_dist(s, distance, length, flush) \
{ uch len = (uch)(length); \
ush dist = (ush)(distance); \
s->d_buf[s->sym_next] = dist; \
s->l_buf[s->sym_next++] = len; \
dist--; \
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
s->dyn_dtree[d_code(dist)].Freq++; \
flush = (s->sym_next == s->sym_end); \
}
#else
# define _tr_tally_lit(s, c, flush) \
{ uch cc = (c); \
s->sym_buf[s->sym_next++] = 0; \
@@ -337,6 +367,7 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
s->dyn_dtree[d_code(dist)].Freq++; \
flush = (s->sym_next == s->sym_end); \
}
#endif
#else
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
# define _tr_tally_dist(s, distance, length, flush) \
+13 -18
View File
@@ -1,5 +1,5 @@
/* gzguts.h -- zlib internal header definitions for gz* operations
* Copyright (C) 2004-2019 Mark Adler
* Copyright (C) 2004-2024 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -7,9 +7,8 @@
# ifndef _LARGEFILE_SOURCE
# define _LARGEFILE_SOURCE 1
# endif
# ifdef _FILE_OFFSET_BITS
# undef _FILE_OFFSET_BITS
# endif
# undef _FILE_OFFSET_BITS
# undef _TIME_BITS
#endif
#ifdef HAVE_HIDDEN
@@ -119,8 +118,8 @@
/* gz* functions always use library allocation functions */
#ifndef STDC
extern voidp malloc OF((uInt size));
extern void free OF((voidpf ptr));
extern voidp malloc(uInt size);
extern void free(voidpf ptr);
#endif
/* get errno and strerror definition */
@@ -138,10 +137,10 @@
/* 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));
ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *);
ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int);
ZEXTERN z_off64_t ZEXPORT gztell64(gzFile);
ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile);
#endif
/* default memLevel */
@@ -203,17 +202,13 @@ typedef struct {
typedef gz_state FAR *gz_statep;
/* shared functions */
void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
void ZLIB_INTERNAL gz_error(gz_statep, int, const char *);
#if defined UNDER_CE
char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
char ZLIB_INTERNAL *gz_strwinerror(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
unsigned ZLIB_INTERNAL gz_intmax(void);
#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
+1 -1
View File
@@ -8,4 +8,4 @@
subject to change. Applications should only use zlib.h.
*/
void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start);
+5 -5
View File
@@ -41,8 +41,8 @@ typedef struct {
examples/enough.c found in the zlib distribution. 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
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. */
@@ -57,6 +57,6 @@ typedef enum {
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));
int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens,
unsigned codes, code FAR * FAR *table,
unsigned FAR *bits, unsigned short FAR *work);
+197 -194
View File
@@ -1,7 +1,7 @@
/* zlib.h -- interface of the 'zlib' general purpose compression library
version 1.2.13, October 13th, 2022
version 1.3.1, January 22nd, 2024
Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
Copyright (C) 1995-2024 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
@@ -37,11 +37,11 @@
extern "C" {
#endif
#define ZLIB_VERSION "1.2.13"
#define ZLIB_VERNUM 0x12d0
#define ZLIB_VERSION "1.3.1"
#define ZLIB_VERNUM 0x1310
#define ZLIB_VER_MAJOR 1
#define ZLIB_VER_MINOR 2
#define ZLIB_VER_REVISION 13
#define ZLIB_VER_MINOR 3
#define ZLIB_VER_REVISION 1
#define ZLIB_VER_SUBREVISION 0
/*
@@ -78,8 +78,8 @@ extern "C" {
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));
typedef voidpf (*alloc_func)(voidpf opaque, uInt items, uInt size);
typedef void (*free_func)(voidpf opaque, voidpf address);
struct internal_state;
@@ -217,7 +217,7 @@ typedef gz_header FAR *gz_headerp;
/* basic functions */
ZEXTERN const char * ZEXPORT zlibVersion OF((void));
ZEXTERN const char * ZEXPORT zlibVersion(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
@@ -225,12 +225,12 @@ ZEXTERN const char * ZEXPORT zlibVersion OF((void));
*/
/*
ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
ZEXTERN int ZEXPORT deflateInit(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.
allocation functions. total_in, total_out, adler, and msg are initialized.
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
@@ -247,7 +247,7 @@ ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
*/
ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
ZEXTERN int ZEXPORT deflate(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
@@ -320,8 +320,8 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
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.
avail_out is greater than six when the flush marker begins, in order to avoid
repeated flush markers upon calling deflate() again when avail_out == 0.
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
@@ -360,7 +360,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
*/
ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
ZEXTERN int ZEXPORT deflateEnd(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
@@ -375,7 +375,7 @@ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
/*
ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
ZEXTERN int ZEXPORT inflateInit(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
@@ -383,7 +383,8 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
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.
them to use default allocation functions. total_in, total_out, adler, and
msg are initialized.
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
@@ -397,7 +398,7 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
*/
ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
ZEXTERN int ZEXPORT inflate(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
@@ -517,7 +518,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
*/
ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
ZEXTERN int ZEXPORT inflateEnd(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
@@ -535,12 +536,12 @@ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
*/
/*
ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
int level,
int method,
int windowBits,
int memLevel,
int strategy));
ZEXTERN int ZEXPORT deflateInit2(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 zalloc, zfree and opaque must be initialized before by the caller.
@@ -607,9 +608,9 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
compression: this will be done by deflate().
*/
ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
const Bytef *dictionary,
uInt dictLength));
ZEXTERN int ZEXPORT deflateSetDictionary(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
@@ -651,9 +652,9 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
not perform any compression: this will be done by deflate().
*/
ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm,
Bytef *dictionary,
uInt *dictLength));
ZEXTERN int ZEXPORT deflateGetDictionary(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
@@ -673,8 +674,8 @@ ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm,
stream state is inconsistent.
*/
ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
z_streamp source));
ZEXTERN int ZEXPORT deflateCopy(z_streamp dest,
z_streamp source);
/*
Sets the destination stream as a complete copy of the source stream.
@@ -691,20 +692,20 @@ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
destination.
*/
ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
ZEXTERN int ZEXPORT deflateReset(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.
set unchanged. total_in, total_out, adler, and msg are initialized.
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));
ZEXTERN int ZEXPORT deflateParams(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
@@ -729,7 +730,7 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
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().
applied to 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
@@ -740,11 +741,11 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
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));
ZEXTERN int ZEXPORT deflateTune(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
@@ -757,8 +758,8 @@ ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
*/
ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
uLong sourceLen));
ZEXTERN uLong ZEXPORT deflateBound(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
@@ -772,9 +773,9 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
than Z_FINISH or Z_NO_FLUSH are used.
*/
ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
unsigned *pending,
int *bits));
ZEXTERN int ZEXPORT deflatePending(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
@@ -787,9 +788,9 @@ ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
stream state was inconsistent.
*/
ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
int bits,
int value));
ZEXTERN int ZEXPORT deflatePrime(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
@@ -804,8 +805,8 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
source stream state was inconsistent.
*/
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
gz_headerp head));
ZEXTERN int ZEXPORT deflateSetHeader(z_streamp strm,
gz_headerp head);
/*
deflateSetHeader() provides gzip header information for when a gzip
stream is requested by deflateInit2(). deflateSetHeader() may be called
@@ -821,16 +822,17 @@ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
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().
the time set to zero, and os set to the current operating system, 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));
ZEXTERN int ZEXPORT inflateInit2(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
@@ -883,9 +885,9 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
deferred until inflate() is called.
*/
ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
const Bytef *dictionary,
uInt dictLength));
ZEXTERN int ZEXPORT inflateSetDictionary(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,
@@ -906,9 +908,9 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
inflate().
*/
ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
Bytef *dictionary,
uInt *dictLength));
ZEXTERN int ZEXPORT inflateGetDictionary(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
@@ -921,7 +923,7 @@ ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
stream state is inconsistent.
*/
ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
ZEXTERN int ZEXPORT inflateSync(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
@@ -934,14 +936,14 @@ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
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.
In the success case, the application may save the 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));
ZEXTERN int ZEXPORT inflateCopy(z_streamp dest,
z_streamp source);
/*
Sets the destination stream as a complete copy of the source stream.
@@ -956,18 +958,19 @@ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
destination.
*/
ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
ZEXTERN int ZEXPORT inflateReset(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.
total_in, total_out, adler, and msg are initialized.
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));
ZEXTERN int ZEXPORT inflateReset2(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
@@ -980,9 +983,9 @@ ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
the windowBits parameter is invalid.
*/
ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
int bits,
int value));
ZEXTERN int ZEXPORT inflatePrime(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
@@ -1001,7 +1004,7 @@ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
stream state was inconsistent.
*/
ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
ZEXTERN long ZEXPORT inflateMark(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
@@ -1029,8 +1032,8 @@ ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
source stream state was inconsistent.
*/
ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
gz_headerp head));
ZEXTERN int ZEXPORT inflateGetHeader(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
@@ -1070,8 +1073,8 @@ ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
*/
/*
ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
unsigned char FAR *window));
ZEXTERN int ZEXPORT inflateBackInit(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
@@ -1091,13 +1094,13 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
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));
typedef unsigned (*in_func)(void FAR *,
z_const unsigned char FAR * FAR *);
typedef int (*out_func)(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));
ZEXTERN int ZEXPORT inflateBack(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
@@ -1165,7 +1168,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
cannot return Z_OK.
*/
ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
ZEXTERN int ZEXPORT inflateBackEnd(z_streamp strm);
/*
All memory allocated by inflateBackInit() is freed.
@@ -1173,7 +1176,7 @@ ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
state was inconsistent.
*/
ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
ZEXTERN uLong ZEXPORT zlibCompileFlags(void);
/* Return flags indicating compile-time options.
Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
@@ -1226,8 +1229,8 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
you need special options.
*/
ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen));
ZEXTERN int ZEXPORT compress(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
@@ -1241,9 +1244,9 @@ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
buffer.
*/
ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen,
int level));
ZEXTERN int ZEXPORT compress2(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
@@ -1257,15 +1260,15 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
Z_STREAM_ERROR if the level parameter is invalid.
*/
ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
ZEXTERN uLong ZEXPORT compressBound(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));
ZEXTERN int ZEXPORT uncompress(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
@@ -1282,8 +1285,8 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
buffer with the uncompressed data up to that point.
*/
ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong *sourceLen));
ZEXTERN int ZEXPORT uncompress2(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
@@ -1302,7 +1305,7 @@ ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen,
typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
/*
ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode);
Open the gzip (.gz) file at path for reading and decompressing, or
compressing and writing. The mode parameter is as in fopen ("rb" or "wb")
@@ -1339,7 +1342,7 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
file could not be opened.
*/
ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode);
/*
Associate a gzFile with the file descriptor fd. File descriptors are
obtained from calls like open, dup, creat, pipe or fileno (if the file has
@@ -1362,7 +1365,7 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
will not detect if fd is invalid (unless fd is -1).
*/
ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
ZEXTERN int ZEXPORT gzbuffer(gzFile file, unsigned size);
/*
Set the internal buffer size used by this library's functions for file to
size. The default buffer size is 8192 bytes. This function must be called
@@ -1378,7 +1381,7 @@ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
too late.
*/
ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
ZEXTERN int ZEXPORT gzsetparams(gzFile file, int level, int strategy);
/*
Dynamically update the compression level and strategy for file. See the
description of deflateInit2 for the meaning of these parameters. Previously
@@ -1389,7 +1392,7 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
or Z_MEM_ERROR if there is a memory allocation error.
*/
ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
ZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len);
/*
Read and decompress up to len uncompressed bytes from file into buf. If
the input file is not in gzip format, gzread copies the given number of
@@ -1419,8 +1422,8 @@ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
Z_STREAM_ERROR.
*/
ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
gzFile file));
ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems,
gzFile file);
/*
Read and decompress up to nitems items of size size from file into buf,
otherwise operating as gzread() does. This duplicates the interface of
@@ -1445,14 +1448,14 @@ ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
file, resetting and retrying on end-of-file, when size is not 1.
*/
ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len));
ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len);
/*
Compress and write the len uncompressed bytes at buf to 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));
ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size,
z_size_t nitems, gzFile file);
/*
Compress and write nitems items of size size from buf to file, duplicating
the interface of stdio's fwrite(), with size_t request and return types. If
@@ -1465,7 +1468,7 @@ ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size,
is returned, and the error state is set to Z_STREAM_ERROR.
*/
ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...);
/*
Convert, format, compress, and write the arguments (...) to file under
control of the string format, as in fprintf. gzprintf returns the number of
@@ -1480,7 +1483,7 @@ ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
This can be determined using zlibCompileFlags().
*/
ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s);
/*
Compress and write the given null-terminated string s to file, excluding
the terminating null character.
@@ -1488,7 +1491,7 @@ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
gzputs returns the number of characters written, or -1 in case of error.
*/
ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len);
/*
Read and decompress bytes from file into buf, until len-1 characters are
read, or until a newline character is read and transferred to buf, or an
@@ -1502,13 +1505,13 @@ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
buf are indeterminate.
*/
ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
ZEXTERN int ZEXPORT gzputc(gzFile file, int c);
/*
Compress and write c, converted to an unsigned char, into file. gzputc
returns the value that was written, or -1 in case of error.
*/
ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
ZEXTERN int ZEXPORT gzgetc(gzFile file);
/*
Read and decompress one byte from file. gzgetc returns this byte or -1
in case of end of file or error. This is implemented as a macro for speed.
@@ -1517,7 +1520,7 @@ ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
points to has been clobbered or not.
*/
ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
ZEXTERN int ZEXPORT gzungetc(int c, gzFile file);
/*
Push c back onto the stream for file to be read as the first character on
the next read. At least one character of push-back is always allowed.
@@ -1529,7 +1532,7 @@ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
gzseek() or gzrewind().
*/
ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
ZEXTERN int ZEXPORT gzflush(gzFile file, int flush);
/*
Flush all pending output to file. The parameter flush is as in the
deflate() function. The return value is the zlib error number (see function
@@ -1545,8 +1548,8 @@ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
*/
/*
ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
z_off_t offset, int whence));
ZEXTERN z_off_t ZEXPORT gzseek(gzFile file,
z_off_t offset, int whence);
Set the starting position to offset relative to whence for the next gzread
or gzwrite on file. The offset represents a number of bytes in the
@@ -1564,7 +1567,7 @@ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
would be before the current position.
*/
ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
ZEXTERN int ZEXPORT gzrewind(gzFile file);
/*
Rewind file. This function is supported only for reading.
@@ -1572,7 +1575,7 @@ ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
*/
/*
ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
ZEXTERN z_off_t ZEXPORT gztell(gzFile file);
Return the starting position for the next gzread or gzwrite on file.
This position represents a number of bytes in the uncompressed data stream,
@@ -1583,7 +1586,7 @@ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
*/
/*
ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
ZEXTERN z_off_t ZEXPORT gzoffset(gzFile file);
Return the current compressed (actual) read or write offset of file. This
offset includes the count of bytes that precede the gzip stream, for example
@@ -1592,7 +1595,7 @@ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
be used for a progress indicator. On error, gzoffset() returns -1.
*/
ZEXTERN int ZEXPORT gzeof OF((gzFile file));
ZEXTERN int ZEXPORT gzeof(gzFile file);
/*
Return true (1) if the end-of-file indicator for file has been set while
reading, false (0) otherwise. Note that the end-of-file indicator is set
@@ -1607,7 +1610,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
has grown since the previous end of file was detected.
*/
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
ZEXTERN int ZEXPORT gzdirect(gzFile file);
/*
Return true (1) if file is being copied directly while reading, or false
(0) if file is a gzip stream being decompressed.
@@ -1628,7 +1631,7 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
gzip file reading and decompression, which may not be desired.)
*/
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
ZEXTERN int ZEXPORT gzclose(gzFile file);
/*
Flush all pending output for file, if necessary, close file and
deallocate the (de)compression state. Note that once file is closed, you
@@ -1641,8 +1644,8 @@ ZEXTERN int ZEXPORT gzclose OF((gzFile file));
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));
ZEXTERN int ZEXPORT gzclose_r(gzFile file);
ZEXTERN int ZEXPORT gzclose_w(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
@@ -1653,7 +1656,7 @@ ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
zlib library.
*/
ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum);
/*
Return the error message for the last error which occurred on file.
errnum is set to zlib error number. If an error occurred in the file system
@@ -1669,7 +1672,7 @@ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
functions above that do not distinguish those cases in their return values.
*/
ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
ZEXTERN void ZEXPORT gzclearerr(gzFile file);
/*
Clear 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
@@ -1686,7 +1689,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
library.
*/
ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
ZEXTERN uLong ZEXPORT adler32(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. An Adler-32 value is in the range of a 32-bit
@@ -1706,15 +1709,15 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
if (adler != original_adler) error();
*/
ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf,
z_size_t len));
ZEXTERN uLong ZEXPORT adler32_z(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));
ZEXTERN uLong ZEXPORT adler32_combine(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
@@ -1724,7 +1727,7 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
negative, the result has no meaning or utility.
*/
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
ZEXTERN uLong ZEXPORT crc32(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. A CRC-32 value is in the range of a 32-bit unsigned integer.
@@ -1742,30 +1745,30 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
if (crc != original_crc) error();
*/
ZEXTERN uLong ZEXPORT crc32_z OF((uLong crc, const Bytef *buf,
z_size_t len));
ZEXTERN uLong ZEXPORT crc32_z(uLong crc, 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));
ZEXTERN uLong ZEXPORT crc32_combine(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.
len2. len2 must be non-negative.
*/
/*
ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t len2));
ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2);
Return the operator corresponding to length len2, to be used with
crc32_combine_op().
crc32_combine_op(). len2 must be non-negative.
*/
ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op));
ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op);
/*
Give the same result as crc32_combine(), using op in place of len2. op is
is generated from len2 by crc32_combine_gen(). This will be faster than
@@ -1778,20 +1781,20 @@ ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op));
/* 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));
ZEXTERN int ZEXPORT deflateInit_(z_streamp strm, int level,
const char *version, int stream_size);
ZEXTERN int ZEXPORT inflateInit_(z_streamp strm,
const char *version, int stream_size);
ZEXTERN int ZEXPORT deflateInit2_(z_streamp strm, int level, int method,
int windowBits, int memLevel,
int strategy, const char *version,
int stream_size);
ZEXTERN int ZEXPORT inflateInit2_(z_streamp strm, int windowBits,
const char *version, int stream_size);
ZEXTERN int ZEXPORT inflateBackInit_(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))
@@ -1836,7 +1839,7 @@ struct gzFile_s {
unsigned char *next;
z_off64_t pos;
};
ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
ZEXTERN int ZEXPORT gzgetc_(gzFile file); /* backward compatibility */
#ifdef Z_PREFIX_SET
# undef z_gzgetc
# define z_gzgetc(g) \
@@ -1853,13 +1856,13 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
* 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));
ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off64_t));
ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *);
ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int);
ZEXTERN z_off64_t ZEXPORT gztell64(gzFile);
ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile);
ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t);
ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t);
ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t);
#endif
#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
@@ -1881,50 +1884,50 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
# define crc32_combine_gen crc32_combine_gen64
# 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));
ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t));
ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *);
ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int);
ZEXTERN z_off_t ZEXPORT gztell64(gzFile);
ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile);
ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t);
ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t);
ZEXTERN uLong ZEXPORT crc32_combine_gen64(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));
ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t));
ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *);
ZEXTERN z_off_t ZEXPORT gzseek(gzFile, z_off_t, int);
ZEXTERN z_off_t ZEXPORT gztell(gzFile);
ZEXTERN z_off_t ZEXPORT gzoffset(gzFile);
ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t);
ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t);
ZEXTERN uLong ZEXPORT crc32_combine_gen(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));
ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t));
ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t);
ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t);
ZEXTERN uLong ZEXPORT crc32_combine_gen(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));
ZEXTERN const char * ZEXPORT zError(int);
ZEXTERN int ZEXPORT inflateSyncPoint(z_streamp);
ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table(void);
ZEXTERN int ZEXPORT inflateUndermine(z_streamp, int);
ZEXTERN int ZEXPORT inflateValidate(z_streamp, int);
ZEXTERN unsigned long ZEXPORT inflateCodesUsed(z_streamp);
ZEXTERN int ZEXPORT inflateResetKeep(z_streamp);
ZEXTERN int ZEXPORT deflateResetKeep(z_streamp);
#if defined(_WIN32) && !defined(Z_SOLO)
ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
const char *mode));
ZEXTERN gzFile ZEXPORT gzopen_w(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));
ZEXTERN int ZEXPORTVA gzvprintf(gzFile file,
const char *format,
va_list va);
# endif
#endif
+12 -24
View File
@@ -1,5 +1,5 @@
/* zutil.h -- internal interface and configuration of the compression library
* Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler
* Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -56,7 +56,7 @@ 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_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)]
#define ERR_RETURN(strm,err) \
return (strm->msg = ERR_MSG(err), (err))
@@ -157,18 +157,6 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
# 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() */
# else
# define fdopen(fd,type) _fdopen(fd,type)
# endif
#endif
#if defined(__BORLANDC__) && !defined(MSDOS)
#pragma warn -8004
#pragma warn -8008
@@ -178,9 +166,9 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
/* 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));
ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t));
ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t);
ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t);
ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t);
#endif
/* common defaults */
@@ -219,16 +207,16 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
# 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));
void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len);
int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len);
void ZLIB_INTERNAL zmemzero(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));
extern void ZLIB_INTERNAL z_error(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 ;}
@@ -245,9 +233,9 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
#endif
#ifndef Z_SOLO
voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
unsigned size));
void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items,
unsigned size);
void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr);
#endif
#define ZALLOC(strm, items, size) \
+5 -27
View File
@@ -7,8 +7,6 @@
#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 */
@@ -60,11 +58,7 @@ local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
#endif
/* ========================================================================= */
uLong ZEXPORT adler32_z(adler, buf, len)
uLong adler;
const Bytef *buf;
z_size_t len;
{
uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) {
unsigned long sum2;
unsigned n;
@@ -131,20 +125,12 @@ uLong ZEXPORT adler32_z(adler, buf, len)
}
/* ========================================================================= */
uLong ZEXPORT adler32(adler, buf, len)
uLong adler;
const Bytef *buf;
uInt len;
{
uLong ZEXPORT adler32(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;
{
local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2) {
unsigned long sum1;
unsigned long sum2;
unsigned rem;
@@ -169,18 +155,10 @@ local uLong adler32_combine_(adler1, adler2, len2)
}
/* ========================================================================= */
uLong ZEXPORT adler32_combine(adler1, adler2, len2)
uLong adler1;
uLong adler2;
z_off_t len2;
{
uLong ZEXPORT adler32_combine(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;
{
uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) {
return adler32_combine_(adler1, adler2, len2);
}
+5 -16
View File
@@ -19,13 +19,8 @@
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;
{
int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source,
uLong sourceLen, int level) {
z_stream stream;
int err;
const uInt max = (uInt)-1;
@@ -65,12 +60,8 @@ int ZEXPORT compress2(dest, destLen, source, sourceLen, level)
/* ===========================================================================
*/
int ZEXPORT compress(dest, destLen, source, sourceLen)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
{
int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source,
uLong sourceLen) {
return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
}
@@ -78,9 +69,7 @@ int ZEXPORT compress(dest, destLen, source, sourceLen)
If the default memLevel or windowBits for deflateInit() is changed, then
this function needs to be updated.
*/
uLong ZEXPORT compressBound(sourceLen)
uLong sourceLen;
{
uLong ZEXPORT compressBound(uLong sourceLen) {
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
(sourceLen >> 25) + 13;
}
+86 -162
View File
@@ -103,19 +103,6 @@
# define ARMCRC32
#endif
/* Local functions. */
local z_crc_t multmodp OF((z_crc_t a, z_crc_t b));
local z_crc_t x2nmodp OF((z_off64_t n, unsigned k));
#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
local z_word_t byte_swap OF((z_word_t word));
#endif
#if defined(W) && !defined(ARMCRC32)
local z_crc_t crc_word OF((z_word_t data));
local z_word_t crc_word_big OF((z_word_t data));
#endif
#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
/*
Swap the bytes in a z_word_t to convert between little and big endian. Any
@@ -123,9 +110,7 @@ local z_crc_t x2nmodp OF((z_off64_t n, unsigned k));
instruction, if one is available. This assumes that word_t is either 32 bits
or 64 bits.
*/
local z_word_t byte_swap(word)
z_word_t word;
{
local z_word_t byte_swap(z_word_t word) {
# if W == 8
return
(word & 0xff00000000000000) >> 56 |
@@ -146,24 +131,77 @@ local z_word_t byte_swap(word)
}
#endif
#ifdef DYNAMIC_CRC_TABLE
/* =========================================================================
* Table of powers of x for combining CRC-32s, filled in by make_crc_table()
* below.
*/
local z_crc_t FAR x2n_table[32];
#else
/* =========================================================================
* Tables for byte-wise and braided CRC-32 calculations, and a table of powers
* of x for combining CRC-32s, all made by make_crc_table().
*/
# include "crc32.h"
#endif
/* CRC polynomial. */
#define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */
#ifdef DYNAMIC_CRC_TABLE
/*
Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial,
reflected. For speed, this requires that a not be zero.
*/
local z_crc_t multmodp(z_crc_t a, z_crc_t b) {
z_crc_t m, p;
m = (z_crc_t)1 << 31;
p = 0;
for (;;) {
if (a & m) {
p ^= b;
if ((a & (m - 1)) == 0)
break;
}
m >>= 1;
b = b & 1 ? (b >> 1) ^ POLY : b >> 1;
}
return p;
}
/*
Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been
initialized.
*/
local z_crc_t x2nmodp(z_off64_t n, unsigned k) {
z_crc_t p;
p = (z_crc_t)1 << 31; /* x^0 == 1 */
while (n) {
if (n & 1)
p = multmodp(x2n_table[k & 31], p);
n >>= 1;
k++;
}
return p;
}
#ifdef DYNAMIC_CRC_TABLE
/* =========================================================================
* Build the tables for byte-wise and braided CRC-32 calculations, and a table
* of powers of x for combining CRC-32s.
*/
local z_crc_t FAR crc_table[256];
local z_crc_t FAR x2n_table[32];
local void make_crc_table OF((void));
#ifdef W
local z_word_t FAR crc_big_table[256];
local z_crc_t FAR crc_braid_table[W][256];
local z_word_t FAR crc_braid_big_table[W][256];
local void braid OF((z_crc_t [][256], z_word_t [][256], int, int));
local void braid(z_crc_t [][256], z_word_t [][256], int, int);
#endif
#ifdef MAKECRCH
local void write_table OF((FILE *, const z_crc_t FAR *, int));
local void write_table32hi OF((FILE *, const z_word_t FAR *, int));
local void write_table64 OF((FILE *, const z_word_t FAR *, int));
local void write_table(FILE *, const z_crc_t FAR *, int);
local void write_table32hi(FILE *, const z_word_t FAR *, int);
local void write_table64(FILE *, const z_word_t FAR *, int);
#endif /* MAKECRCH */
/*
@@ -176,7 +214,6 @@ local void make_crc_table OF((void));
/* Definition of once functionality. */
typedef struct once_s once_t;
local void once OF((once_t *, void (*)(void)));
/* Check for the availability of atomics. */
#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \
@@ -196,10 +233,7 @@ struct once_s {
invoke once() at the same time. The state must be a once_t initialized with
ONCE_INIT.
*/
local void once(state, init)
once_t *state;
void (*init)(void);
{
local void once(once_t *state, void (*init)(void)) {
if (!atomic_load(&state->done)) {
if (atomic_flag_test_and_set(&state->begun))
while (!atomic_load(&state->done))
@@ -222,10 +256,7 @@ struct once_s {
/* Test and set. Alas, not atomic, but tries to minimize the period of
vulnerability. */
local int test_and_set OF((int volatile *));
local int test_and_set(flag)
int volatile *flag;
{
local int test_and_set(int volatile *flag) {
int was;
was = *flag;
@@ -234,10 +265,7 @@ local int test_and_set(flag)
}
/* Run the provided init() function once. This is not thread-safe. */
local void once(state, init)
once_t *state;
void (*init)(void);
{
local void once(once_t *state, void (*init)(void)) {
if (!state->done) {
if (test_and_set(&state->begun))
while (!state->done)
@@ -279,8 +307,7 @@ local once_t made = ONCE_INIT;
combinations of CRC register values and incoming bytes.
*/
local void make_crc_table()
{
local void make_crc_table(void) {
unsigned i, j, n;
z_crc_t p;
@@ -447,11 +474,7 @@ local void make_crc_table()
Write the 32-bit values in table[0..k-1] to out, five per line in
hexadecimal separated by commas.
*/
local void write_table(out, table, k)
FILE *out;
const z_crc_t FAR *table;
int k;
{
local void write_table(FILE *out, const z_crc_t FAR *table, int k) {
int n;
for (n = 0; n < k; n++)
@@ -464,11 +487,7 @@ local void write_table(out, table, k)
Write the high 32-bits of each value in table[0..k-1] to out, five per line
in hexadecimal separated by commas.
*/
local void write_table32hi(out, table, k)
FILE *out;
const z_word_t FAR *table;
int k;
{
local void write_table32hi(FILE *out, const z_word_t FAR *table, int k) {
int n;
for (n = 0; n < k; n++)
@@ -484,11 +503,7 @@ int k;
bits. If not, then the type cast and format string can be adjusted
accordingly.
*/
local void write_table64(out, table, k)
FILE *out;
const z_word_t FAR *table;
int k;
{
local void write_table64(FILE *out, const z_word_t FAR *table, int k) {
int n;
for (n = 0; n < k; n++)
@@ -498,8 +513,7 @@ local void write_table64(out, table, k)
}
/* Actually do the deed. */
int main()
{
int main(void) {
make_crc_table();
return 0;
}
@@ -511,12 +525,7 @@ int main()
Generate the little and big-endian braid tables for the given n and z_word_t
size w. Each array must have room for w blocks of 256 elements.
*/
local void braid(ltl, big, n, w)
z_crc_t ltl[][256];
z_word_t big[][256];
int n;
int w;
{
local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) {
int k;
z_crc_t i, p, q;
for (k = 0; k < w; k++) {
@@ -531,69 +540,13 @@ local void braid(ltl, big, n, w)
}
#endif
#else /* !DYNAMIC_CRC_TABLE */
/* ========================================================================
* Tables for byte-wise and braided CRC-32 calculations, and a table of powers
* of x for combining CRC-32s, all made by make_crc_table().
*/
#include "crc32.h"
#endif /* DYNAMIC_CRC_TABLE */
/* ========================================================================
* Routines used for CRC calculation. Some are also required for the table
* generation above.
*/
/*
Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial,
reflected. For speed, this requires that a not be zero.
*/
local z_crc_t multmodp(a, b)
z_crc_t a;
z_crc_t b;
{
z_crc_t m, p;
m = (z_crc_t)1 << 31;
p = 0;
for (;;) {
if (a & m) {
p ^= b;
if ((a & (m - 1)) == 0)
break;
}
m >>= 1;
b = b & 1 ? (b >> 1) ^ POLY : b >> 1;
}
return p;
}
/*
Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been
initialized.
*/
local z_crc_t x2nmodp(n, k)
z_off64_t n;
unsigned k;
{
z_crc_t p;
p = (z_crc_t)1 << 31; /* x^0 == 1 */
while (n) {
if (n & 1)
p = multmodp(x2n_table[k & 31], p);
n >>= 1;
k++;
}
return p;
}
/* =========================================================================
* This function can be used by asm versions of crc32(), and to force the
* generation of the CRC tables in a threaded application.
*/
const z_crc_t FAR * ZEXPORT get_crc_table()
{
const z_crc_t FAR * ZEXPORT get_crc_table(void) {
#ifdef DYNAMIC_CRC_TABLE
once(&made, make_crc_table);
#endif /* DYNAMIC_CRC_TABLE */
@@ -619,11 +572,8 @@ const z_crc_t FAR * ZEXPORT get_crc_table()
#define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */
#define Z_BATCH_MIN 800 /* fewest words in a final batch */
unsigned long ZEXPORT crc32_z(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
z_size_t len;
{
unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
z_size_t len) {
z_crc_t val;
z_word_t crc1, crc2;
const z_word_t *word;
@@ -723,18 +673,14 @@ unsigned long ZEXPORT crc32_z(crc, buf, len)
least-significant byte of the word as the first byte of data, without any pre
or post conditioning. This is used to combine the CRCs of each braid.
*/
local z_crc_t crc_word(data)
z_word_t data;
{
local z_crc_t crc_word(z_word_t data) {
int k;
for (k = 0; k < W; k++)
data = (data >> 8) ^ crc_table[data & 0xff];
return (z_crc_t)data;
}
local z_word_t crc_word_big(data)
z_word_t data;
{
local z_word_t crc_word_big(z_word_t data) {
int k;
for (k = 0; k < W; k++)
data = (data << 8) ^
@@ -745,11 +691,8 @@ local z_word_t crc_word_big(data)
#endif
/* ========================================================================= */
unsigned long ZEXPORT crc32_z(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
z_size_t len;
{
unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
z_size_t len) {
/* Return initial CRC, if requested. */
if (buf == Z_NULL) return 0;
@@ -781,8 +724,8 @@ unsigned long ZEXPORT crc32_z(crc, buf, len)
words = (z_word_t const *)buf;
/* Do endian check at execution time instead of compile time, since ARM
processors can change the endianess at execution time. If the
compiler knows what the endianess will be, it can optimize out the
processors can change the endianness at execution time. If the
compiler knows what the endianness will be, it can optimize out the
check and the unused branch. */
endian = 1;
if (*(unsigned char *)&endian) {
@@ -1069,20 +1012,13 @@ unsigned long ZEXPORT crc32_z(crc, buf, len)
#endif
/* ========================================================================= */
unsigned long ZEXPORT crc32(crc, buf, len)
unsigned long crc;
const unsigned char FAR *buf;
uInt len;
{
unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf,
uInt len) {
return crc32_z(crc, buf, len);
}
/* ========================================================================= */
uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
uLong crc1;
uLong crc2;
z_off64_t len2;
{
uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) {
#ifdef DYNAMIC_CRC_TABLE
once(&made, make_crc_table);
#endif /* DYNAMIC_CRC_TABLE */
@@ -1090,18 +1026,12 @@ uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
}
/* ========================================================================= */
uLong ZEXPORT crc32_combine(crc1, crc2, len2)
uLong crc1;
uLong crc2;
z_off_t len2;
{
uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) {
return crc32_combine64(crc1, crc2, (z_off64_t)len2);
}
/* ========================================================================= */
uLong ZEXPORT crc32_combine_gen64(len2)
z_off64_t len2;
{
uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) {
#ifdef DYNAMIC_CRC_TABLE
once(&made, make_crc_table);
#endif /* DYNAMIC_CRC_TABLE */
@@ -1109,17 +1039,11 @@ uLong ZEXPORT crc32_combine_gen64(len2)
}
/* ========================================================================= */
uLong ZEXPORT crc32_combine_gen(len2)
z_off_t len2;
{
uLong ZEXPORT crc32_combine_gen(z_off_t len2) {
return crc32_combine_gen64((z_off64_t)len2);
}
/* ========================================================================= */
uLong ZEXPORT crc32_combine_op(crc1, crc2, op)
uLong crc1;
uLong crc2;
uLong op;
{
uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) {
return multmodp(op, crc1) ^ (crc2 & 0xffffffff);
}
+267 -345
View File
@@ -1,5 +1,5 @@
/* deflate.c -- compress data using the deflation algorithm
* Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
* Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -52,7 +52,7 @@
#include "deflate.h"
const char deflate_copyright[] =
" deflate 1.2.13 Copyright 1995-2022 Jean-loup Gailly and Mark Adler ";
" deflate 1.3.1 Copyright 1995-2024 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
@@ -60,9 +60,6 @@ const char deflate_copyright[] =
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 */
@@ -70,29 +67,16 @@ typedef enum {
finish_done /* finish done, accept no more input or output */
} block_state;
typedef block_state (*compress_func) OF((deflate_state *s, int flush));
typedef block_state (*compress_func)(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));
local block_state deflate_stored(deflate_state *s, int flush);
local block_state deflate_fast(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));
local uInt longest_match OF((deflate_state *s, IPos cur_match));
#ifdef ZLIB_DEBUG
local void check_match OF((deflate_state *s, IPos start, IPos match,
int length));
local block_state deflate_slow(deflate_state *s, int flush);
#endif
local block_state deflate_rle(deflate_state *s, int flush);
local block_state deflate_huff(deflate_state *s, int flush);
/* ===========================================================================
* Local data
@@ -195,9 +179,12 @@ local const config configuration_table[10] = {
* 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;
{
#if defined(__has_feature)
# if __has_feature(memory_sanitizer)
__attribute__((no_sanitize("memory")))
# endif
#endif
local void slide_hash(deflate_state *s) {
unsigned n, m;
Posf *p;
uInt wsize = s->w_size;
@@ -221,30 +208,177 @@ local void slide_hash(s)
#endif
}
/* ===========================================================================
* 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(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;
}
/* ===========================================================================
* 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(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;
if (s->insert > s->strstart)
s->insert = s->strstart;
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");
}
/* ========================================================================= */
int ZEXPORT deflateInit_(strm, level, version, stream_size)
z_streamp strm;
int level;
const char *version;
int stream_size;
{
int ZEXPORT deflateInit_(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;
{
int ZEXPORT deflateInit2_(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;
@@ -363,7 +497,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
* symbols from which it is being constructed.
*/
s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4);
s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS);
s->pending_buf_size = (ulg)s->lit_bufsize * 4;
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
@@ -373,8 +507,14 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
deflateEnd (strm);
return Z_MEM_ERROR;
}
#ifdef LIT_MEM
s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1));
s->l_buf = s->pending_buf + (s->lit_bufsize << 2);
s->sym_end = s->lit_bufsize - 1;
#else
s->sym_buf = s->pending_buf + s->lit_bufsize;
s->sym_end = (s->lit_bufsize - 1) * 3;
#endif
/* We avoid equality with lit_bufsize*3 because of wraparound at 64K
* on 16 bit machines and because stored blocks are restricted to
* 64K-1 bytes.
@@ -390,9 +530,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
/* =========================================================================
* Check for a valid deflate stream state. Return 0 if ok, 1 if not.
*/
local int deflateStateCheck(strm)
z_streamp strm;
{
local int deflateStateCheck(z_streamp strm) {
deflate_state *s;
if (strm == Z_NULL ||
strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
@@ -413,11 +551,8 @@ local int deflateStateCheck(strm)
}
/* ========================================================================= */
int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength)
z_streamp strm;
const Bytef *dictionary;
uInt dictLength;
{
int ZEXPORT deflateSetDictionary(z_streamp strm, const Bytef *dictionary,
uInt dictLength) {
deflate_state *s;
uInt str, n;
int wrap;
@@ -482,11 +617,8 @@ int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength)
}
/* ========================================================================= */
int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength)
z_streamp strm;
Bytef *dictionary;
uInt *dictLength;
{
int ZEXPORT deflateGetDictionary(z_streamp strm, Bytef *dictionary,
uInt *dictLength) {
deflate_state *s;
uInt len;
@@ -504,9 +636,7 @@ int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength)
}
/* ========================================================================= */
int ZEXPORT deflateResetKeep(strm)
z_streamp strm;
{
int ZEXPORT deflateResetKeep(z_streamp strm) {
deflate_state *s;
if (deflateStateCheck(strm)) {
@@ -541,10 +671,32 @@ int ZEXPORT deflateResetKeep(strm)
return Z_OK;
}
/* ===========================================================================
* Initialize the "longest match" routines for a new zlib stream
*/
local void lm_init(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;
}
/* ========================================================================= */
int ZEXPORT deflateReset(strm)
z_streamp strm;
{
int ZEXPORT deflateReset(z_streamp strm) {
int ret;
ret = deflateResetKeep(strm);
@@ -554,10 +706,7 @@ int ZEXPORT deflateReset(strm)
}
/* ========================================================================= */
int ZEXPORT deflateSetHeader(strm, head)
z_streamp strm;
gz_headerp head;
{
int ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head) {
if (deflateStateCheck(strm) || strm->state->wrap != 2)
return Z_STREAM_ERROR;
strm->state->gzhead = head;
@@ -565,11 +714,7 @@ int ZEXPORT deflateSetHeader(strm, head)
}
/* ========================================================================= */
int ZEXPORT deflatePending(strm, pending, bits)
unsigned *pending;
int *bits;
z_streamp strm;
{
int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) {
if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
if (pending != Z_NULL)
*pending = strm->state->pending;
@@ -579,19 +724,21 @@ int ZEXPORT deflatePending(strm, pending, bits)
}
/* ========================================================================= */
int ZEXPORT deflatePrime(strm, bits, value)
z_streamp strm;
int bits;
int value;
{
int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) {
deflate_state *s;
int put;
if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
s = strm->state;
#ifdef LIT_MEM
if (bits < 0 || bits > 16 ||
(uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3))
return Z_BUF_ERROR;
#else
if (bits < 0 || bits > 16 ||
s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3))
return Z_BUF_ERROR;
#endif
do {
put = Buf_size - s->bi_valid;
if (put > bits)
@@ -606,11 +753,7 @@ int ZEXPORT deflatePrime(strm, bits, value)
}
/* ========================================================================= */
int ZEXPORT deflateParams(strm, level, strategy)
z_streamp strm;
int level;
int strategy;
{
int ZEXPORT deflateParams(z_streamp strm, int level, int strategy) {
deflate_state *s;
compress_func func;
@@ -655,13 +798,8 @@ int ZEXPORT deflateParams(strm, level, strategy)
}
/* ========================================================================= */
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;
{
int ZEXPORT deflateTune(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;
@@ -697,10 +835,7 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
*
* Shifts are used to approximate divisions, for speed.
*/
uLong ZEXPORT deflateBound(strm, sourceLen)
z_streamp strm;
uLong sourceLen;
{
uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) {
deflate_state *s;
uLong fixedlen, storelen, wraplen;
@@ -756,7 +891,8 @@ uLong ZEXPORT deflateBound(strm, sourceLen)
/* if not default parameters, return one of the conservative bounds */
if (s->w_bits != 15 || s->hash_bits != 8 + 7)
return (s->w_bits <= s->hash_bits ? fixedlen : storelen) + wraplen;
return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) +
wraplen;
/* default settings: return tight bound for that case -- ~0.03% overhead
plus a small constant */
@@ -769,10 +905,7 @@ uLong ZEXPORT deflateBound(strm, sourceLen)
* 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;
{
local void putShortMSB(deflate_state *s, uInt b) {
put_byte(s, (Byte)(b >> 8));
put_byte(s, (Byte)(b & 0xff));
}
@@ -783,9 +916,7 @@ local void putShortMSB(s, b)
* 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;
{
local void flush_pending(z_streamp strm) {
unsigned len;
deflate_state *s = strm->state;
@@ -816,10 +947,7 @@ local void flush_pending(strm)
} while (0)
/* ========================================================================= */
int ZEXPORT deflate(strm, flush)
z_streamp strm;
int flush;
{
int ZEXPORT deflate(z_streamp strm, int flush) {
int old_flush; /* value of flush param for previous deflate call */
deflate_state *s;
@@ -1131,9 +1259,7 @@ int ZEXPORT deflate(strm, flush)
}
/* ========================================================================= */
int ZEXPORT deflateEnd(strm)
z_streamp strm;
{
int ZEXPORT deflateEnd(z_streamp strm) {
int status;
if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -1157,11 +1283,10 @@ int ZEXPORT deflateEnd(strm)
* 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;
{
int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) {
#ifdef MAXSEG_64K
(void)dest;
(void)source;
return Z_STREAM_ERROR;
#else
deflate_state *ds;
@@ -1185,7 +1310,7 @@ int ZEXPORT deflateCopy(dest, source)
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));
ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4);
ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS);
if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
ds->pending_buf == Z_NULL) {
@@ -1196,10 +1321,15 @@ int ZEXPORT deflateCopy(dest, source)
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);
zmemcpy(ds->pending_buf, ss->pending_buf, ds->lit_bufsize * LIT_BUFS);
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
#ifdef LIT_MEM
ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1));
ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2);
#else
ds->sym_buf = ds->pending_buf + ds->lit_bufsize;
#endif
ds->l_desc.dyn_tree = ds->dyn_ltree;
ds->d_desc.dyn_tree = ds->dyn_dtree;
@@ -1209,66 +1339,6 @@ int ZEXPORT deflateCopy(dest, source)
#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
/* ===========================================================================
* Set match_start to the longest match starting at the given string and
@@ -1279,10 +1349,7 @@ local void lm_init(s)
* string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
* OUT assertion: the match length is not greater than s->lookahead.
*/
local uInt longest_match(s, cur_match)
deflate_state *s;
IPos cur_match; /* current match */
{
local uInt longest_match(deflate_state *s, IPos cur_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 */
@@ -1430,10 +1497,7 @@ local uInt longest_match(s, cur_match)
/* ---------------------------------------------------------------------------
* Optimized version for FASTEST only
*/
local uInt longest_match(s, cur_match)
deflate_state *s;
IPos cur_match; /* current match */
{
local uInt longest_match(deflate_state *s, IPos cur_match) {
register Bytef *scan = s->window + s->strstart; /* current string */
register Bytef *match; /* matched string */
register int len; /* length of current match */
@@ -1494,19 +1558,23 @@ local uInt longest_match(s, cur_match)
/* ===========================================================================
* 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;
{
local void check_match(deflate_state *s, IPos start, IPos 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);
Bytef *back = s->window + (int)match, *here = s->window + start;
IPos len = length;
if (match == (IPos)-1) {
/* match starts one byte before the current window -- just compare the
subsequent length-1 bytes */
back++;
here++;
len--;
}
if (zmemcmp(back, here, len) != EQUAL) {
fprintf(stderr, " start %u, match %d, length %d\n",
start, (int)match, length);
do {
fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
} while (--length != 0);
fprintf(stderr, "(%02x %02x)", *back++, *here++);
} while (--len != 0);
z_error("invalid match");
}
if (z_verbose > 1) {
@@ -1518,137 +1586,6 @@ local void check_match(s, start, match, length)
# 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;
if (s->insert > s->strstart)
s->insert = s->strstart;
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.
@@ -1691,10 +1628,7 @@ local void fill_window(s)
* copied. It is most efficient with large input and output buffers, which
* maximizes the opportunities to have a single copy from next_in to next_out.
*/
local block_state deflate_stored(s, flush)
deflate_state *s;
int flush;
{
local block_state deflate_stored(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.
@@ -1878,10 +1812,7 @@ local block_state deflate_stored(s, flush)
* 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;
{
local block_state deflate_fast(deflate_state *s, int flush) {
IPos hash_head; /* head of the hash chain */
int bflush; /* set if current block must be flushed */
@@ -1980,10 +1911,7 @@ local block_state deflate_fast(s, flush)
* 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;
{
local block_state deflate_slow(deflate_state *s, int flush) {
IPos hash_head; /* head of hash chain */
int bflush; /* set if current block must be flushed */
@@ -2111,10 +2039,7 @@ local block_state deflate_slow(s, flush)
* 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;
{
local block_state deflate_rle(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 */
@@ -2185,10 +2110,7 @@ local block_state deflate_rle(s, flush)
* 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;
{
local block_state deflate_huff(deflate_state *s, int flush) {
int bflush; /* set if current block must be flushed */
for (;;) {
+1 -3
View File
@@ -8,9 +8,7 @@
/* 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;
{
int ZEXPORT gzclose(gzFile file) {
#ifndef NO_GZCOMPRESS
gz_statep state;
+28 -85
View File
@@ -1,5 +1,5 @@
/* gzlib.c -- zlib functions common to reading and writing gzip files
* Copyright (C) 2004-2019 Mark Adler
* Copyright (C) 2004-2024 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -15,10 +15,6 @@
#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
@@ -30,9 +26,7 @@ local gzFile gz_open OF((const void *, int, const char *));
The gz_strwinerror function does not change the current setting of
GetLastError. */
char ZLIB_INTERNAL *gz_strwinerror(error)
DWORD error;
{
char ZLIB_INTERNAL *gz_strwinerror(DWORD error) {
static char buf[1024];
wchar_t *msgbuf;
@@ -72,9 +66,7 @@ char ZLIB_INTERNAL *gz_strwinerror(error)
#endif /* UNDER_CE */
/* Reset gzip file state */
local void gz_reset(state)
gz_statep state;
{
local void gz_reset(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 */
@@ -90,11 +82,7 @@ local void gz_reset(state)
}
/* 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;
{
local gzFile gz_open(const void *path, int fd, const char *mode) {
gz_statep state;
z_size_t len;
int oflag;
@@ -269,26 +257,17 @@ local gzFile gz_open(path, fd, mode)
}
/* -- see zlib.h -- */
gzFile ZEXPORT gzopen(path, mode)
const char *path;
const char *mode;
{
gzFile ZEXPORT gzopen(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;
{
gzFile ZEXPORT gzopen64(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;
{
gzFile ZEXPORT gzdopen(int fd, const char *mode) {
char *path; /* identifier for error messages */
gzFile gz;
@@ -306,19 +285,13 @@ gzFile ZEXPORT gzdopen(fd, mode)
/* -- see zlib.h -- */
#ifdef WIDECHAR
gzFile ZEXPORT gzopen_w(path, mode)
const wchar_t *path;
const char *mode;
{
gzFile ZEXPORT gzopen_w(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;
{
int ZEXPORT gzbuffer(gzFile file, unsigned size) {
gz_statep state;
/* get internal structure and check integrity */
@@ -335,16 +308,14 @@ int ZEXPORT gzbuffer(file, size)
/* 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 */
if (size < 8)
size = 8; /* needed to behave well with flushing */
state->want = size;
return 0;
}
/* -- see zlib.h -- */
int ZEXPORT gzrewind(file)
gzFile file;
{
int ZEXPORT gzrewind(gzFile file) {
gz_statep state;
/* get internal structure */
@@ -365,11 +336,7 @@ int ZEXPORT gzrewind(file)
}
/* -- see zlib.h -- */
z_off64_t ZEXPORT gzseek64(file, offset, whence)
gzFile file;
z_off64_t offset;
int whence;
{
z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) {
unsigned n;
z_off64_t ret;
gz_statep state;
@@ -442,11 +409,7 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence)
}
/* -- see zlib.h -- */
z_off_t ZEXPORT gzseek(file, offset, whence)
gzFile file;
z_off_t offset;
int whence;
{
z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence) {
z_off64_t ret;
ret = gzseek64(file, (z_off64_t)offset, whence);
@@ -454,9 +417,7 @@ z_off_t ZEXPORT gzseek(file, offset, whence)
}
/* -- see zlib.h -- */
z_off64_t ZEXPORT gztell64(file)
gzFile file;
{
z_off64_t ZEXPORT gztell64(gzFile file) {
gz_statep state;
/* get internal structure and check integrity */
@@ -471,9 +432,7 @@ z_off64_t ZEXPORT gztell64(file)
}
/* -- see zlib.h -- */
z_off_t ZEXPORT gztell(file)
gzFile file;
{
z_off_t ZEXPORT gztell(gzFile file) {
z_off64_t ret;
ret = gztell64(file);
@@ -481,9 +440,7 @@ z_off_t ZEXPORT gztell(file)
}
/* -- see zlib.h -- */
z_off64_t ZEXPORT gzoffset64(file)
gzFile file;
{
z_off64_t ZEXPORT gzoffset64(gzFile file) {
z_off64_t offset;
gz_statep state;
@@ -504,9 +461,7 @@ z_off64_t ZEXPORT gzoffset64(file)
}
/* -- see zlib.h -- */
z_off_t ZEXPORT gzoffset(file)
gzFile file;
{
z_off_t ZEXPORT gzoffset(gzFile file) {
z_off64_t ret;
ret = gzoffset64(file);
@@ -514,9 +469,7 @@ z_off_t ZEXPORT gzoffset(file)
}
/* -- see zlib.h -- */
int ZEXPORT gzeof(file)
gzFile file;
{
int ZEXPORT gzeof(gzFile file) {
gz_statep state;
/* get internal structure and check integrity */
@@ -531,10 +484,7 @@ int ZEXPORT gzeof(file)
}
/* -- see zlib.h -- */
const char * ZEXPORT gzerror(file, errnum)
gzFile file;
int *errnum;
{
const char * ZEXPORT gzerror(gzFile file, int *errnum) {
gz_statep state;
/* get internal structure and check integrity */
@@ -552,9 +502,7 @@ const char * ZEXPORT gzerror(file, errnum)
}
/* -- see zlib.h -- */
void ZEXPORT gzclearerr(file)
gzFile file;
{
void ZEXPORT gzclearerr(gzFile file) {
gz_statep state;
/* get internal structure and check integrity */
@@ -578,11 +526,7 @@ void ZEXPORT gzclearerr(file)
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;
{
void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) {
/* free previously allocated message and clear */
if (state->msg != NULL) {
if (state->err != Z_MEM_ERROR)
@@ -619,21 +563,20 @@ void ZLIB_INTERNAL gz_error(state, err, 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;
unsigned ZLIB_INTERNAL gz_intmax(void) {
#ifdef INT_MAX
return INT_MAX;
#else
unsigned p = 1, q;
do {
q = p;
p <<= 1;
p++;
} while (p > q);
return q >> 1;
}
#endif
}
+20 -68
View File
@@ -5,25 +5,12 @@
#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;
{
local int gz_load(gz_statep state, unsigned char *buf, unsigned len,
unsigned *have) {
int ret;
unsigned get, max = ((unsigned)-1 >> 2) + 1;
@@ -53,9 +40,7 @@ local int gz_load(state, buf, len, have)
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;
{
local int gz_avail(gz_statep state) {
unsigned got;
z_streamp strm = &(state->strm);
@@ -88,9 +73,7 @@ local int gz_avail(state)
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;
{
local int gz_look(gz_statep state) {
z_streamp strm = &(state->strm);
/* allocate read buffers and inflate memory */
@@ -170,9 +153,7 @@ local int gz_look(state)
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;
{
local int gz_decomp(gz_statep state) {
int ret = Z_OK;
unsigned had;
z_streamp strm = &(state->strm);
@@ -224,9 +205,7 @@ local int gz_decomp(state)
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;
{
local int gz_fetch(gz_statep state) {
z_streamp strm = &(state->strm);
do {
@@ -254,10 +233,7 @@ local int gz_fetch(state)
}
/* 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;
{
local int gz_skip(gz_statep state, z_off64_t len) {
unsigned n;
/* skip over len bytes or reach end-of-file, whichever comes first */
@@ -289,11 +265,7 @@ local int gz_skip(state, len)
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;
{
local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) {
z_size_t got;
unsigned n;
@@ -370,11 +342,7 @@ local z_size_t gz_read(state, buf, len)
}
/* -- see zlib.h -- */
int ZEXPORT gzread(file, buf, len)
gzFile file;
voidp buf;
unsigned len;
{
int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) {
gz_statep state;
/* get internal structure */
@@ -406,12 +374,7 @@ int ZEXPORT gzread(file, buf, 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 ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, gzFile file) {
z_size_t len;
gz_statep state;
@@ -442,9 +405,7 @@ z_size_t ZEXPORT gzfread(buf, size, nitems, file)
#else
# undef gzgetc
#endif
int ZEXPORT gzgetc(file)
gzFile file;
{
int ZEXPORT gzgetc(gzFile file) {
unsigned char buf[1];
gz_statep state;
@@ -469,17 +430,12 @@ int ZEXPORT gzgetc(file)
return gz_read(state, buf, 1) < 1 ? -1 : buf[0];
}
int ZEXPORT gzgetc_(file)
gzFile file;
{
int ZEXPORT gzgetc_(gzFile file) {
return gzgetc(file);
}
/* -- see zlib.h -- */
int ZEXPORT gzungetc(c, file)
int c;
gzFile file;
{
int ZEXPORT gzungetc(int c, gzFile file) {
gz_statep state;
/* get internal structure */
@@ -487,6 +443,10 @@ int ZEXPORT gzungetc(c, file)
return -1;
state = (gz_statep)file;
/* in case this was just opened, set up the input buffer */
if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
(void)gz_look(state);
/* 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))
@@ -536,11 +496,7 @@ int ZEXPORT gzungetc(c, file)
}
/* -- see zlib.h -- */
char * ZEXPORT gzgets(file, buf, len)
gzFile file;
char *buf;
int len;
{
char * ZEXPORT gzgets(gzFile file, char *buf, int len) {
unsigned left, n;
char *str;
unsigned char *eol;
@@ -600,9 +556,7 @@ char * ZEXPORT gzgets(file, buf, len)
}
/* -- see zlib.h -- */
int ZEXPORT gzdirect(file)
gzFile file;
{
int ZEXPORT gzdirect(gzFile file) {
gz_statep state;
/* get internal structure */
@@ -620,9 +574,7 @@ int ZEXPORT gzdirect(file)
}
/* -- see zlib.h -- */
int ZEXPORT gzclose_r(file)
gzFile file;
{
int ZEXPORT gzclose_r(gzFile file) {
int ret, err;
gz_statep state;
+19 -65
View File
@@ -5,18 +5,10 @@
#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;
{
local int gz_init(gz_statep state) {
int ret;
z_streamp strm = &(state->strm);
@@ -70,10 +62,7 @@ local int gz_init(state)
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;
{
local int gz_comp(gz_statep state, int flush) {
int ret, writ;
unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
z_streamp strm = &(state->strm);
@@ -151,10 +140,7 @@ local int gz_comp(state, flush)
/* 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;
{
local int gz_zero(gz_statep state, z_off64_t len) {
int first;
unsigned n;
z_streamp strm = &(state->strm);
@@ -184,11 +170,7 @@ local int gz_zero(state, len)
/* 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;
{
local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) {
z_size_t put = len;
/* if len is zero, avoid unnecessary operations */
@@ -252,11 +234,7 @@ local z_size_t gz_write(state, buf, len)
}
/* -- see zlib.h -- */
int ZEXPORT gzwrite(file, buf, len)
gzFile file;
voidpc buf;
unsigned len;
{
int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) {
gz_statep state;
/* get internal structure */
@@ -280,12 +258,8 @@ int ZEXPORT gzwrite(file, 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 ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems,
gzFile file) {
z_size_t len;
gz_statep state;
@@ -310,10 +284,7 @@ z_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
}
/* -- see zlib.h -- */
int ZEXPORT gzputc(file, c)
gzFile file;
int c;
{
int ZEXPORT gzputc(gzFile file, int c) {
unsigned have;
unsigned char buf[1];
gz_statep state;
@@ -358,10 +329,7 @@ int ZEXPORT gzputc(file, c)
}
/* -- see zlib.h -- */
int ZEXPORT gzputs(file, s)
gzFile file;
const char *s;
{
int ZEXPORT gzputs(gzFile file, const char *s) {
z_size_t len, put;
gz_statep state;
@@ -388,8 +356,7 @@ int ZEXPORT gzputs(file, s)
#include <stdarg.h>
/* -- see zlib.h -- */
int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
{
int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) {
int len;
unsigned left;
char *next;
@@ -460,8 +427,7 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
return len;
}
int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
{
int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) {
va_list va;
int ret;
@@ -474,13 +440,10 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
#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;
{
int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3,
int a4, int a5, int a6, int a7, int a8, int a9, int a10,
int a11, int a12, int a13, int a14, int a15, int a16,
int a17, int a18, int a19, int a20) {
unsigned len, left;
char *next;
gz_statep state;
@@ -562,10 +525,7 @@ int ZEXPORTVA gzprintf(file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
#endif
/* -- see zlib.h -- */
int ZEXPORT gzflush(file, flush)
gzFile file;
int flush;
{
int ZEXPORT gzflush(gzFile file, int flush) {
gz_statep state;
/* get internal structure */
@@ -594,11 +554,7 @@ int ZEXPORT gzflush(file, flush)
}
/* -- see zlib.h -- */
int ZEXPORT gzsetparams(file, level, strategy)
gzFile file;
int level;
int strategy;
{
int ZEXPORT gzsetparams(gzFile file, int level, int strategy) {
gz_statep state;
z_streamp strm;
@@ -609,7 +565,7 @@ int ZEXPORT gzsetparams(file, level, strategy)
strm = &(state->strm);
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct)
return Z_STREAM_ERROR;
/* if no change is requested, then do nothing */
@@ -636,9 +592,7 @@ int ZEXPORT gzsetparams(file, level, strategy)
}
/* -- see zlib.h -- */
int ZEXPORT gzclose_w(file)
gzFile file;
{
int ZEXPORT gzclose_w(gzFile file) {
int ret = Z_OK;
gz_statep state;
+7 -23
View File
@@ -15,9 +15,6 @@
#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.
@@ -25,13 +22,9 @@ local void fixedtables OF((struct inflate_state FAR *state));
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;
{
int ZEXPORT inflateBackInit_(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] ||
@@ -80,9 +73,7 @@ int stream_size;
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;
{
local void fixedtables(struct inflate_state FAR *state) {
#ifdef BUILDFIXED
static int virgin = 1;
static code *lenfix, *distfix;
@@ -248,13 +239,8 @@ struct inflate_state FAR *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;
{
int ZEXPORT inflateBack(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 */
@@ -632,9 +618,7 @@ void FAR *out_desc;
return ret;
}
int ZEXPORT inflateBackEnd(strm)
z_streamp strm;
{
int ZEXPORT inflateBackEnd(z_streamp strm) {
if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
return Z_STREAM_ERROR;
ZFREE(strm, strm->state);
+1 -4
View File
@@ -47,10 +47,7 @@
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 */
{
void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) {
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 */
+31 -100
View File
@@ -91,20 +91,7 @@
# 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;
{
local int inflateStateCheck(z_streamp strm) {
struct inflate_state FAR *state;
if (strm == Z_NULL ||
strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
@@ -116,9 +103,7 @@ z_streamp strm;
return 0;
}
int ZEXPORT inflateResetKeep(strm)
z_streamp strm;
{
int ZEXPORT inflateResetKeep(z_streamp strm) {
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -142,9 +127,7 @@ z_streamp strm;
return Z_OK;
}
int ZEXPORT inflateReset(strm)
z_streamp strm;
{
int ZEXPORT inflateReset(z_streamp strm) {
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -155,10 +138,7 @@ z_streamp strm;
return inflateResetKeep(strm);
}
int ZEXPORT inflateReset2(strm, windowBits)
z_streamp strm;
int windowBits;
{
int ZEXPORT inflateReset2(z_streamp strm, int windowBits) {
int wrap;
struct inflate_state FAR *state;
@@ -195,12 +175,8 @@ int windowBits;
return inflateReset(strm);
}
int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
z_streamp strm;
int windowBits;
const char *version;
int stream_size;
{
int ZEXPORT inflateInit2_(z_streamp strm, int windowBits,
const char *version, int stream_size) {
int ret;
struct inflate_state FAR *state;
@@ -239,22 +215,17 @@ int stream_size;
return ret;
}
int ZEXPORT inflateInit_(strm, version, stream_size)
z_streamp strm;
const char *version;
int stream_size;
{
int ZEXPORT inflateInit_(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;
{
int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) {
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
if (bits == 0)
return Z_OK;
state = (struct inflate_state FAR *)strm->state;
if (bits < 0) {
state->hold = 0;
@@ -278,9 +249,7 @@ int value;
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;
{
local void fixedtables(struct inflate_state FAR *state) {
#ifdef BUILDFIXED
static int virgin = 1;
static code *lenfix, *distfix;
@@ -342,7 +311,7 @@ struct inflate_state FAR *state;
a.out > inffixed.h
*/
void makefixed()
void makefixed(void)
{
unsigned low, size;
struct inflate_state state;
@@ -396,11 +365,7 @@ void makefixed()
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;
{
local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) {
struct inflate_state FAR *state;
unsigned dist;
@@ -622,10 +587,7 @@ unsigned copy;
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;
{
int ZEXPORT inflate(z_streamp strm, int flush) {
struct inflate_state FAR *state;
z_const unsigned char FAR *next; /* next input */
unsigned char FAR *put; /* next output */
@@ -1301,9 +1263,7 @@ int flush;
return ret;
}
int ZEXPORT inflateEnd(strm)
z_streamp strm;
{
int ZEXPORT inflateEnd(z_streamp strm) {
struct inflate_state FAR *state;
if (inflateStateCheck(strm))
return Z_STREAM_ERROR;
@@ -1315,11 +1275,8 @@ z_streamp strm;
return Z_OK;
}
int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
z_streamp strm;
Bytef *dictionary;
uInt *dictLength;
{
int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary,
uInt *dictLength) {
struct inflate_state FAR *state;
/* check state */
@@ -1338,11 +1295,8 @@ uInt *dictLength;
return Z_OK;
}
int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
z_streamp strm;
const Bytef *dictionary;
uInt dictLength;
{
int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary,
uInt dictLength) {
struct inflate_state FAR *state;
unsigned long dictid;
int ret;
@@ -1373,10 +1327,7 @@ uInt dictLength;
return Z_OK;
}
int ZEXPORT inflateGetHeader(strm, head)
z_streamp strm;
gz_headerp head;
{
int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) {
struct inflate_state FAR *state;
/* check state */
@@ -1401,11 +1352,8 @@ gz_headerp head;
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;
{
local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf,
unsigned len) {
unsigned got;
unsigned next;
@@ -1424,9 +1372,7 @@ unsigned len;
return next;
}
int ZEXPORT inflateSync(strm)
z_streamp strm;
{
int ZEXPORT inflateSync(z_streamp strm) {
unsigned len; /* number of bytes to look at or looked at */
int flags; /* temporary to save header status */
unsigned long in, out; /* temporary to save total_in and total_out */
@@ -1441,7 +1387,7 @@ z_streamp strm;
/* if first time, start search in bit buffer */
if (state->mode != SYNC) {
state->mode = SYNC;
state->hold <<= state->bits & 7;
state->hold >>= state->bits & 7;
state->bits -= state->bits & 7;
len = 0;
while (state->bits >= 8) {
@@ -1482,9 +1428,7 @@ z_streamp strm;
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;
{
int ZEXPORT inflateSyncPoint(z_streamp strm) {
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -1492,10 +1436,7 @@ z_streamp strm;
return state->mode == STORED && state->bits == 0;
}
int ZEXPORT inflateCopy(dest, source)
z_streamp dest;
z_streamp source;
{
int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) {
struct inflate_state FAR *state;
struct inflate_state FAR *copy;
unsigned char FAR *window;
@@ -1539,10 +1480,7 @@ z_streamp source;
return Z_OK;
}
int ZEXPORT inflateUndermine(strm, subvert)
z_streamp strm;
int subvert;
{
int ZEXPORT inflateUndermine(z_streamp strm, int subvert) {
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -1557,10 +1495,7 @@ int subvert;
#endif
}
int ZEXPORT inflateValidate(strm, check)
z_streamp strm;
int check;
{
int ZEXPORT inflateValidate(z_streamp strm, int check) {
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
@@ -1572,9 +1507,7 @@ int check;
return Z_OK;
}
long ZEXPORT inflateMark(strm)
z_streamp strm;
{
long ZEXPORT inflateMark(z_streamp strm) {
struct inflate_state FAR *state;
if (inflateStateCheck(strm))
@@ -1585,9 +1518,7 @@ z_streamp strm;
(state->mode == MATCH ? state->was - state->length : 0));
}
unsigned long ZEXPORT inflateCodesUsed(strm)
z_streamp strm;
{
unsigned long ZEXPORT inflateCodesUsed(z_streamp strm) {
struct inflate_state FAR *state;
if (inflateStateCheck(strm)) return (unsigned long)-1;
state = (struct inflate_state FAR *)strm->state;
+6 -11
View File
@@ -1,5 +1,5 @@
/* inftrees.c -- generate Huffman trees for efficient decoding
* Copyright (C) 1995-2022 Mark Adler
* Copyright (C) 1995-2024 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -9,7 +9,7 @@
#define MAXBITS 15
const char inflate_copyright[] =
" inflate 1.2.13 Copyright 1995-2022 Mark Adler ";
" inflate 1.3.1 Copyright 1995-2024 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
@@ -29,14 +29,9 @@ const char inflate_copyright[] =
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;
{
int ZLIB_INTERNAL inflate_table(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 */
@@ -62,7 +57,7 @@ unsigned short FAR *work;
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, 194, 65};
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 77};
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,
+239 -303
View File
@@ -1,5 +1,5 @@
/* trees.c -- output deflated data using Huffman coding
* Copyright (C) 1995-2021 Jean-loup Gailly
* Copyright (C) 1995-2024 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
*/
@@ -122,39 +122,116 @@ struct static_tree_desc_s {
int max_length; /* max bit length for the codes */
};
local const static_tree_desc static_l_desc =
#ifdef NO_INIT_GLOBAL_POINTERS
# define TCONST
#else
# define TCONST const
#endif
local TCONST static_tree_desc static_l_desc =
{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
local const static_tree_desc static_d_desc =
local TCONST static_tree_desc static_d_desc =
{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
local const static_tree_desc static_bl_desc =
local TCONST static_tree_desc static_bl_desc =
{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
/* ===========================================================================
* Local (static) routines in this file.
* 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)); \
}
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 code, int len));
local void bi_windup OF((deflate_state *s));
local void bi_flush OF((deflate_state *s));
/* ===========================================================================
* 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(unsigned code, int len) {
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(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(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
}
/* ===========================================================================
* 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(ct_data *tree, int max_code, ushf *bl_count) {
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));
}
}
#ifdef GEN_TREES_H
local void gen_trees_header OF((void));
local void gen_trees_header(void);
#endif
#ifndef ZLIB_DEBUG
@@ -167,27 +244,12 @@ local void gen_trees_header OF((void));
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 */
{
local void send_bits(deflate_state *s, int value, int length) {
Tracevv((stderr," l %2d v %4x ", length, value));
Assert(length > 0 && length <= 15, "invalid length");
s->bits_sent += (ulg)length;
@@ -229,8 +291,7 @@ local void send_bits(s, value, length)
/* ===========================================================================
* Initialize the various 'constant' tables.
*/
local void tr_static_init()
{
local void tr_static_init(void) {
#if defined(GEN_TREES_H) || !defined(STDC)
static int static_init_done = 0;
int n; /* iterates over tree elements */
@@ -323,8 +384,7 @@ local void tr_static_init()
((i) == (last)? "\n};\n\n" : \
((i) % (width) == (width) - 1 ? ",\n" : ", "))
void gen_trees_header()
{
void gen_trees_header(void) {
FILE *header = fopen("trees.h", "w");
int i;
@@ -373,12 +433,26 @@ void gen_trees_header()
}
#endif /* GEN_TREES_H */
/* ===========================================================================
* Initialize a new block.
*/
local void init_block(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->sym_next = s->matches = 0;
}
/* ===========================================================================
* Initialize the tree data structures for a new zlib stream.
*/
void ZLIB_INTERNAL _tr_init(s)
deflate_state *s;
{
void ZLIB_INTERNAL _tr_init(deflate_state *s) {
tr_static_init();
s->l_desc.dyn_tree = s->dyn_ltree;
@@ -401,24 +475,6 @@ void ZLIB_INTERNAL _tr_init(s)
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->sym_next = s->matches = 0;
}
#define SMALLEST 1
/* Index within the heap array of least frequent node in the Huffman tree */
@@ -448,11 +504,7 @@ local void init_block(s)
* 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 */
{
local void pqdownheap(deflate_state *s, ct_data *tree, int k) {
int v = s->heap[k];
int j = k << 1; /* left son of k */
while (j <= s->heap_len) {
@@ -483,10 +535,7 @@ local void pqdownheap(s, tree, k)
* 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 */
{
local void gen_bitlen(deflate_state *s, tree_desc *desc) {
ct_data *tree = desc->dyn_tree;
int max_code = desc->max_code;
const ct_data *stree = desc->stat_desc->static_tree;
@@ -561,48 +610,9 @@ local void gen_bitlen(s, desc)
}
}
/* ===========================================================================
* 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));
}
}
#ifdef DUMP_BL_TREE
# include <stdio.h>
#endif
/* ===========================================================================
* Construct one Huffman tree and assigns the code bit strings and lengths.
@@ -612,10 +622,7 @@ local void gen_codes(tree, max_code, bl_count)
* 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 */
{
local void build_tree(deflate_state *s, tree_desc *desc) {
ct_data *tree = desc->dyn_tree;
const ct_data *stree = desc->stat_desc->static_tree;
int elems = desc->stat_desc->elems;
@@ -700,11 +707,7 @@ local void build_tree(s, desc)
* 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 */
{
local void scan_tree(deflate_state *s, ct_data *tree, int max_code) {
int n; /* iterates over all tree elements */
int prevlen = -1; /* last emitted length */
int curlen; /* length of current code */
@@ -745,11 +748,7 @@ local void scan_tree(s, tree, max_code)
* 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 */
{
local void send_tree(deflate_state *s, ct_data *tree, int max_code) {
int n; /* iterates over all tree elements */
int prevlen = -1; /* last emitted length */
int curlen; /* length of current code */
@@ -796,9 +795,7 @@ local void send_tree(s, tree, max_code)
* 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;
{
local int build_bl_tree(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 */
@@ -831,10 +828,8 @@ local int build_bl_tree(s)
* 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 */
{
local void send_all_trees(deflate_state *s, int lcodes, int dcodes,
int blcodes) {
int rank; /* index in bl_order */
Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
@@ -860,12 +855,8 @@ local void send_all_trees(s, lcodes, dcodes, blcodes)
/* ===========================================================================
* 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 */
{
void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf,
ulg stored_len, int last) {
send_bits(s, (STORED_BLOCK<<1) + last, 3); /* send block type */
bi_windup(s); /* align on byte boundary */
put_short(s, (ush)stored_len);
@@ -884,9 +875,7 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
/* ===========================================================================
* 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;
{
void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s) {
bi_flush(s);
}
@@ -894,9 +883,7 @@ void ZLIB_INTERNAL _tr_flush_bits(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;
{
void ZLIB_INTERNAL _tr_align(deflate_state *s) {
send_bits(s, STATIC_TREES<<1, 3);
send_code(s, END_BLOCK, static_ltree);
#ifdef ZLIB_DEBUG
@@ -905,16 +892,108 @@ void ZLIB_INTERNAL _tr_align(s)
bi_flush(s);
}
/* ===========================================================================
* Send the block data compressed using the given Huffman trees
*/
local void compress_block(deflate_state *s, const ct_data *ltree,
const ct_data *dtree) {
unsigned dist; /* distance of matched string */
int lc; /* match length or unmatched char (if dist == 0) */
unsigned sx = 0; /* running index in symbol buffers */
unsigned code; /* the code to send */
int extra; /* number of extra bits to send */
if (s->sym_next != 0) do {
#ifdef LIT_MEM
dist = s->d_buf[sx];
lc = s->l_buf[sx++];
#else
dist = s->sym_buf[sx++] & 0xff;
dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;
lc = s->sym_buf[sx++];
#endif
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 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 for no overlay of pending_buf on needed symbols */
#ifdef LIT_MEM
Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow");
#else
Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
#endif
} while (sx < s->sym_next);
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
* "block list" (0..6, 14..25, 28..31).
* b) There is at least one printable character belonging to the
* "allow 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(deflate_state *s) {
/* block_mask is the bit mask of block-listed bytes
* set bits 0..6, 14..25, and 28..31
* 0xf3ffc07f = binary 11110011111111111100000001111111
*/
unsigned long block_mask = 0xf3ffc07fUL;
int n;
/* Check for non-textual ("block-listed") bytes. */
for (n = 0; n <= 31; n++, block_mask >>= 1)
if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0))
return Z_BINARY;
/* Check for textual ("allow-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 "block-listed" or "allow-listed" bytes:
* this stream either is empty or has tolerated ("gray-listed") bytes only.
*/
return Z_BINARY;
}
/* ===========================================================================
* 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 */
{
void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf,
ulg stored_len, int last) {
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 */
@@ -1011,14 +1090,15 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, 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 (dist==0) */
{
int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) {
#ifdef LIT_MEM
s->d_buf[s->sym_next] = (ush)dist;
s->l_buf[s->sym_next++] = (uch)lc;
#else
s->sym_buf[s->sym_next++] = (uch)dist;
s->sym_buf[s->sym_next++] = (uch)(dist >> 8);
s->sym_buf[s->sym_next++] = (uch)lc;
#endif
if (dist == 0) {
/* lc is the unmatched char */
s->dyn_ltree[lc].Freq++;
@@ -1035,147 +1115,3 @@ int ZLIB_INTERNAL _tr_tally(s, dist, lc)
}
return (s->sym_next == s->sym_end);
}
/* ===========================================================================
* 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 sx = 0; /* running index in sym_buf */
unsigned code; /* the code to send */
int extra; /* number of extra bits to send */
if (s->sym_next != 0) do {
dist = s->sym_buf[sx++] & 0xff;
dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;
lc = s->sym_buf[sx++];
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 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 sym_buf is ok: */
Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
} while (sx < s->sym_next);
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
* "block list" (0..6, 14..25, 28..31).
* b) There is at least one printable character belonging to the
* "allow 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;
{
/* block_mask is the bit mask of block-listed bytes
* set bits 0..6, 14..25, and 28..31
* 0xf3ffc07f = binary 11110011111111111100000001111111
*/
unsigned long block_mask = 0xf3ffc07fUL;
int n;
/* Check for non-textual ("block-listed") bytes. */
for (n = 0; n <= 31; n++, block_mask >>= 1)
if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0))
return Z_BINARY;
/* Check for textual ("allow-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 "block-listed" or "allow-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
}
+4 -12
View File
@@ -24,12 +24,8 @@
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;
{
int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source,
uLong *sourceLen) {
z_stream stream;
int err;
const uInt max = (uInt)-1;
@@ -83,11 +79,7 @@ int ZEXPORT uncompress2(dest, destLen, source, sourceLen)
err;
}
int ZEXPORT uncompress(dest, destLen, source, sourceLen)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
{
int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source,
uLong sourceLen) {
return uncompress2(dest, destLen, source, &sourceLen);
}
+7 -11
View File
@@ -1,5 +1,5 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
* Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -243,7 +243,11 @@
#endif
#ifdef Z_SOLO
typedef unsigned long z_size_t;
# ifdef _WIN64
typedef unsigned long long z_size_t;
# else
typedef unsigned long z_size_t;
# endif
#else
# define z_longlong long long
# if defined(NO_SIZE_T)
@@ -298,14 +302,6 @@
# 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
@@ -522,7 +518,7 @@ typedef uLong FAR uLongf;
#if !defined(_WIN32) && defined(Z_LARGE64)
# define z_off64_t off64_t
#else
# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
# if defined(_WIN32) && !defined(__GNUC__)
# define z_off64_t __int64
# else
# define z_off64_t z_off_t
+24 -14
View File
@@ -1,8 +1,9 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
* Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#ifndef ZCONF_H
#define ZCONF_H
@@ -37,6 +38,9 @@
# define crc32 z_crc32
# define crc32_combine z_crc32_combine
# define crc32_combine64 z_crc32_combine64
# define crc32_combine_gen z_crc32_combine_gen
# define crc32_combine_gen64 z_crc32_combine_gen64
# define crc32_combine_op z_crc32_combine_op
# define crc32_z z_crc32_z
# define deflate z_deflate
# define deflateBound z_deflateBound
@@ -237,7 +241,11 @@
#endif
#ifdef Z_SOLO
typedef unsigned long z_size_t;
# ifdef _WIN64
typedef unsigned long long z_size_t;
# else
typedef unsigned long z_size_t;
# endif
#else
# define z_longlong long long
# if defined(NO_SIZE_T)
@@ -292,14 +300,6 @@
# 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
@@ -348,6 +348,9 @@
# ifdef FAR
# undef FAR
# endif
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
@@ -466,11 +469,18 @@ typedef uLong FAR uLongf;
# undef _LARGEFILE64_SOURCE
#endif
#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
# define Z_HAVE_UNISTD_H
#ifndef Z_HAVE_UNISTD_H
# ifdef __WATCOMC__
# define Z_HAVE_UNISTD_H
# endif
#endif
#ifndef Z_HAVE_UNISTD_H
# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32)
# define Z_HAVE_UNISTD_H
# endif
#endif
#ifndef Z_SOLO
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
# if defined(Z_HAVE_UNISTD_H)
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
# ifdef VMS
# include <unixio.h> /* for off_t */
@@ -506,7 +516,7 @@ typedef uLong FAR uLongf;
#if !defined(_WIN32) && defined(Z_LARGE64)
# define z_off64_t off64_t
#else
# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
# if defined(_WIN32) && !defined(__GNUC__)
# define z_off64_t __int64
# else
# define z_off64_t z_off_t
+16 -44
View File
@@ -24,13 +24,11 @@ z_const char * const z_errmsg[10] = {
};
const char * ZEXPORT zlibVersion()
{
const char * ZEXPORT zlibVersion(void) {
return ZLIB_VERSION;
}
uLong ZEXPORT zlibCompileFlags()
{
uLong ZEXPORT zlibCompileFlags(void) {
uLong flags;
flags = 0;
@@ -121,9 +119,7 @@ uLong ZEXPORT zlibCompileFlags()
# endif
int ZLIB_INTERNAL z_verbose = verbose;
void ZLIB_INTERNAL z_error(m)
char *m;
{
void ZLIB_INTERNAL z_error(char *m) {
fprintf(stderr, "%s\n", m);
exit(1);
}
@@ -132,9 +128,7 @@ void ZLIB_INTERNAL z_error(m)
/* exported to allow conversion of error code to string for compress() and
* uncompress()
*/
const char * ZEXPORT zError(err)
int err;
{
const char * ZEXPORT zError(int err) {
return ERR_MSG(err);
}
@@ -148,22 +142,14 @@ const char * ZEXPORT zError(err)
#ifndef HAVE_MEMCPY
void ZLIB_INTERNAL zmemcpy(dest, source, len)
Bytef* dest;
const Bytef* source;
uInt len;
{
void ZLIB_INTERNAL zmemcpy(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;
{
int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) {
uInt j;
for (j = 0; j < len; j++) {
@@ -172,10 +158,7 @@ int ZLIB_INTERNAL zmemcmp(s1, s2, len)
return 0;
}
void ZLIB_INTERNAL zmemzero(dest, len)
Bytef* dest;
uInt len;
{
void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) {
if (len == 0) return;
do {
*dest++ = 0; /* ??? to be unrolled */
@@ -216,8 +199,7 @@ local ptr_table table[MAX_PTR];
* a protected system like OS/2. Use Microsoft C instead.
*/
voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size)
{
voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) {
voidpf buf;
ulg bsize = (ulg)items*size;
@@ -242,8 +224,7 @@ voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size)
return buf;
}
void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr)
{
void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) {
int n;
(void)opaque;
@@ -279,14 +260,12 @@ void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr)
# define _hfree hfree
#endif
voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size)
{
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 ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) {
(void)opaque;
_hfree(ptr);
}
@@ -299,25 +278,18 @@ void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr)
#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));
extern voidp malloc(uInt size);
extern voidp calloc(uInt items, uInt size);
extern void free(voidpf ptr);
#endif
voidpf ZLIB_INTERNAL zcalloc(opaque, items, size)
voidpf opaque;
unsigned items;
unsigned size;
{
voidpf ZLIB_INTERNAL zcalloc(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 ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) {
(void)opaque;
free(ptr);
}
+8 -1
View File
@@ -6,7 +6,14 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-03-11 Gabriele Cosmo (field-V11-02-07)
## 2025-06-13 Gabriele Cosmo (field-V11-03-02)
- Fixed compilation warning in G4QSStepper and minor code formatting.
## 2025-06-02 John Apostolakis & Mattias Portnoy (field-V11-03-01)
- Changed implementation of QSS integration method to QSS v2
by Mattias Portnoy (Univ. of Buenos Aires)
## 2025-03-11 Gabriele Cosmo (field-V11-03-00)
- Added missing guard in G4TMagFieldEquation header and minor cleanup.
Fixes [GitHub PR #83](https://github.com/Geant4/geant4/pull/83).
@@ -46,6 +46,7 @@ class G4VFSALIntegrationStepper;
class G4MagneticField;
class G4CachedMagneticField;
class G4HelixHeum;
class G4QSStepper;
class G4ChordFinder
{
@@ -151,7 +152,7 @@ class G4ChordFinder
G4MagIntegratorStepper* fNewFSALStepperOwned = nullptr;
std::unique_ptr<G4HelixHeum> fLongStepper;
G4CachedMagneticField* fCachedField = nullptr;
// G4VFSALIntegrationStepper* fOldFSALStepperOwned = nullptr;
G4QSStepper* fQssStepperOwned = nullptr;
G4EquationOfMotion* fEquation = nullptr;
};
@@ -57,9 +57,6 @@ class G4QSSDriver : public G4InterpolationDriver<T, true>
void OnComputeStep(const G4FieldTrack* track) override
{
Base::OnComputeStep(track);
#ifdef GEANT4_DUMP_STEPPER_STATS
this->GetStepper()->stats.steps++;
#endif
}
void SetPrecision(G4double dq_rel, G4double dq_min);
@@ -68,9 +68,11 @@ class G4QSSMessenger : public G4UImessenger
public:
G4double dQMin = 0;
G4double dQRel = 0;
G4double dQMin = 0.00001;
G4double dQRel = 0.001;
G4double trialProposedStepModifier = 1.0;
G4int maxSubsteps = 5000;
G4int QssOrder = 2;
private:
@@ -80,6 +82,7 @@ class G4QSSMessenger : public G4UImessenger
G4UIcmdWithADouble* dQRelCmd;
G4UIcmdWithAString* stepperSelectorCmd;
G4UIcmdWithADouble* trialProposedStepModifierCmd;
G4UIcmdWithAnInteger* maxSubstepsCmd;
};
#endif // GEANT4_G4QSSMessenger_H
@@ -26,560 +26,181 @@
// G4QSStepper
//
// QSS Integrator Stepper
// Authors: Lucio Santi, Rodrigo Castro (Univ. Buenos Aires) - 2018-2021
//
// Authors - version 1 : Lucio Santi, Rodrigo Castro (Univ. Buenos Aires) - 2018-2021
// - version 2 : Mattias Portnoy (Univ. Buenos Aires) - 2024
// --------------------------------------------------------------------
#ifndef QSS_Stepper_HH
#define QSS_Stepper_HH 1
#ifndef G4QSS_STEPPER_HH
#define G4QSS_STEPPER_HH 1
#include "G4FieldTrack.hh"
#include "G4FieldUtils.hh"
#include "G4LineSection.hh"
#include "G4MagIntegratorStepper.hh"
#include "G4QSS2.hh"
#include "G4QSS3.hh"
#include "G4QSSDriver.hh"
#include "G4QSSMessenger.hh"
#include "G4VIntegrationDriver.hh"
#include "G4qss_misc.hh"
#include "G4QSSubstepStruct.hh"
#include <cmath>
#include <cassert>
// Maximum allowed number of QSS substeps per integration step
#define QSS_MAX_SUBSTEPS 1000
template <class QSS>
class G4QSStepper : public G4MagIntegratorStepper
{
public:
G4QSStepper(G4EquationOfMotion* EqRhs,
G4int numberOfVariables = 6,
G4bool primary = true);
~G4QSStepper() override;
G4QSStepper( G4EquationOfMotion* equation,
G4int num_integration_vars,
G4int num_state_vars,
G4bool isFSAL,
G4int verbosity=0 );
void Stepper(const G4double y[],
const G4double dydx[],
G4double h,
G4double yout[],
G4double yerr[]) override;
void Stepper(const G4double yInput[],
const G4double dydx[],
G4double hstep,
G4double yOutput[],
G4double yError[],
G4double dydxOutput[]);
// For calculating the output at the tau fraction of Step
//
inline void SetupInterpolation() {}
inline void Interpolate(G4double tau, G4double yOut[]);
G4double DistChord() const override;
G4int IntegratorOrder() const override { return method->order(); }
void reset(const G4FieldTrack* track);
void SetPrecision(G4double dq_rel, G4double dq_min);
// precision parameters for QSS method
static G4QSStepper<G4QSS2>* build_QSS2(G4EquationOfMotion* EqRhs,
G4int numberOfVariables = 6,
G4bool primary = true);
static G4QSStepper<G4QSS3>* build_QSS3(G4EquationOfMotion* EqRhs,
G4int numberOfVariables = 6,
G4bool primary = true);
inline G4EquationOfMotion* GetSpecificEquation() { return GetEquationOfMotion(); }
inline const field_utils::State& GetYOut() const { return fyOut; }
inline G4double GetLastStepLength() { return fLastStepLength; }
private:
G4QSStepper(QSS* method,
G4EquationOfMotion* EqRhs,
G4QSStepper(G4EquationOfMotion *EqRhs,
G4int numberOfVariables = 6,
G4bool primary = true);
void initialize_data_structs();
static QSS_simulator build_simulator();
virtual ~G4QSStepper();
inline constexpr G4double Cubic_Function(const QSStateVector* states,
G4int index, G4double delta_t);
inline constexpr G4double Parabolic_Function(const QSStateVector* states,
G4int index, G4double delta_t);
inline constexpr G4double Linear_Function(const QSStateVector* states,
G4int index, G4double delta_t);
/* 0 means position type, 1 means velocity type. */
inline constexpr int INDEX_TYPE(G4int i);
inline void set_qss_order(G4int order);
// auxiliary methods
inline void momentum_to_velocity(const G4double* momentum, G4double* out);
void set_relativistic_coeff(const G4double* momentum);
inline void velocity_to_momentum(G4double *y);
// Key methods
void initialize(const G4double y[]);
inline void compare_time_and_update(G4int index, G4int i);
inline G4int get_next_sync_index();
inline void update_field();
inline void save_substep(G4double time, G4double length);
inline void realloc_substeps();
inline void get_state_from_poly(G4double* x, G4double* tx,
G4double time, G4double* state);
inline G4double extrapolate_polynomial(QSStateVector* states,
G4int index, G4double delta_t, G4int order);
inline void extrapolate_all_states_to_t(Substep* substep,
G4double t, G4double* yOut);
inline void recompute_derivatives(int index);
inline void update_time();
/* Moves all the x states of variable index to the current time t. */
inline void update_x(G4int index, G4double t);
inline G4double get_coeff() { return fCoeff_local; }
/* Moves all the q states of variable index to the current t. */
inline void update_q(G4int index, G4double t);
inline void set_coeff(G4double coeff) { fCoeff_local = coeff; }
inline void update_x_position_derivates_using_q(G4int index);
inline void update_x_velocity_derivates_using_q(G4int index);
inline void update_x_derivates_using_q(G4int index);
inline void update_sync_time_one_coefficient(G4int index);
inline void set_charge(G4double q)
{
f_charge_c2 = q * cLight_local * cLight_local; // 89875.5178737;
}
/* Updates when does the x,q distance goes beyond the quantum.
Uses polynomial roots-finding formulas. */
void update_sync_time(G4int index);
inline G4double get_qc2() { return f_charge_c2; }
/* Key method called by driver. */
void Stepper( const G4double y[],
const G4double /*dydx*/ [],
G4double h,
G4double yout[],
G4double /* yerr */ [] ) override;
inline void set_mg() { fMassGamma = f_mass * fGamma2; }
/* Obligatory G4InterpolationDriver methods. */
inline G4int IntegratorOrder() const override;
inline G4EquationOfMotion* GetSpecificEquation();
inline const field_utils::State& GetYOut() const;
inline void set_gamma2(G4double gamma2) { fGamma2 = gamma2; }
inline void set_velocity(G4double v) { fVelocity = v; }
void Interpolate(G4double tau,G4double yOut[]);
inline void velocity_to_momentum(G4double* state);
inline G4double DistChord() const override;
inline void set_gamma(G4double p_sq)
{
set_gamma2(std::sqrt(p_sq / (f_mass * f_mass) + 1));
set_mg();
set_coeff(get_qc2() / fMassGamma);
}
inline void Stepper(const G4double yInput[],
const G4double dydx[],
G4double hstep, G4double yOutput[], G4double yError[],
G4double /*dydxOutput*/ []);
inline void SetupInterpolation();
/* obligatory qss driver methods. */
inline void reset(const G4FieldTrack* track);
inline void SetPrecision(G4double dq_rel, G4double dq_min);
inline G4double GetLastStepLength();
private:
QSS_simulator simulator;
QSS* method;
// Constants
// State
static constexpr int DERIVATIVE_0 = 0;
static constexpr int DERIVATIVE_1 = 1;
static constexpr int DERIVATIVE_2 = 2;
static constexpr int DERIVATIVE_3 = 3;
static constexpr int VX = 3;
static constexpr int VY = 4;
static constexpr int VZ = 5;
static constexpr int POSITION_IDX = 0;
static constexpr int VELOCITY_IDX = 3;
static constexpr int NUMBER_OF_VARIABLES_QSS = 6;
static constexpr G4double INFTY = 1e+20;
/* Used to check if field changed from last update field during substeps. */
G4bool fField_changed = true;
G4bool fTrack_changed = true;
G4int qss_order = 2;
Substeps substeps;
Substep current_substep;
const G4FieldTrack* fCurrent_track = nullptr;
QSStateVector dq_vector;
// Invariants for this track -- during propagation
//
G4double fLastStepLength;
field_utils::State fyIn, fyOut;
G4double fCharge;
G4double fCharge_c2;
G4double fRestMass;
G4double fGamma;
G4double fCoeff; // coeff;
// Cached values -- for tiny speed up
//
G4double fMassOverC ; // was mass_times_gamma_over_speed_of_light;
G4double fInv_mass_over_c;
/* used by interpolation driver, need to copy state here
when stepper finished. */
G4double fYout[12];
// QSS parameters separated into velocity and position
//
G4double dqrel[2] = {0.0,0.0};
G4double dqmin[2] = {0.001,0.001};
G4double f_mass;
static constexpr G4double cLight_local = 299.792458; // should use CLHEP
G4double f_charge_c2;
G4double fMassGamma;
G4double fGamma2;
G4double fCoeff_local;
G4double fVelocity;
G4double fFinal_t;
};
using G4QSStepper_QSS2 = G4QSStepper<G4QSS2>;
using G4QSStepper_QSS3 = G4QSStepper<G4QSS3>;
// ----------------------------------------------------------------------------
// Inline methods
// ----------------------------------------------------------------------------
template <class QSS>
inline G4QSStepper<QSS>::G4QSStepper(QSS* qss, G4EquationOfMotion* EqRhs,
G4int noIntegrationVariables, G4bool)
: G4MagIntegratorStepper(EqRhs, noIntegrationVariables),
simulator(qss->getSimulator()),
method(qss)
{
SetIsQSS(true); // Replaces virtual method IsQSS
fLastStepLength = -1.0;
f_mass = 0;
f_charge_c2 = 0;
fMassGamma = 0;
fGamma2 = 0;
fCoeff_local = 0;
fVelocity = 0;
this->initialize_data_structs();
this->SetPrecision(1e-4, 1e-7); // Default values
}
template <class QSS>
inline G4QSStepper<QSS>::~G4QSStepper()
{
for (auto & i : simulator->SD) { free(i); }
free(SUBSTEPS(this->simulator));
free(this->simulator);
}
template <class QSS>
inline void G4QSStepper<QSS>::Stepper(const G4double yInput[],
const G4double dydx[],
G4double hstep,
G4double yOutput[],
G4double yError[],
G4double /*dydxOutput*/[])
{
Stepper(yInput, dydx, hstep, yOutput, yError);
}
template <class QSS>
inline void G4QSStepper<QSS>::update_time()
{
auto* const sim = this->simulator;
sim->time = sim->nextStateTime[0];
sim->minIndex = 0;
if (sim->nextStateTime[1] < sim->time) {
sim->time = sim->nextStateTime[1];
sim->minIndex = 1;
}
if (sim->nextStateTime[2] < sim->time) {
sim->time = sim->nextStateTime[2];
sim->minIndex = 2;
}
if (sim->nextStateTime[3] < sim->time) {
sim->time = sim->nextStateTime[3];
sim->minIndex = 3;
}
if (sim->nextStateTime[4] < sim->time) {
sim->time = sim->nextStateTime[4];
sim->minIndex = 4;
}
if (sim->nextStateTime[5] < sim->time) {
sim->time = sim->nextStateTime[5];
sim->minIndex = 5;
}
}
template <class QSS>
inline void G4QSStepper<QSS>::Stepper(const G4double yInput[],
const G4double /*DyDx*/[],
G4double max_length,
G4double yOut[],
G4double[] /*yErr[]*/)
{
G4double elapsed;
G4double t, prev_time = 0;
G4double length = 0.;
G4int index;
const G4int coeffs = method->order() + 1;
G4double* tq = simulator->tq;
G4double* tx = simulator->tx;
G4double* dQRel = simulator->dQRel;
G4double* dQMin = simulator->dQMin;
G4double* lqu = simulator->lqu;
G4double* x = simulator->x;
G4int** SD = simulator->SD;
G4int cf0, infCf0;
CUR_SUBSTEP(simulator) = 0;
this->save_substep(0, length);
this->update_time();
t = simulator->time;
index = simulator->minIndex;
while (length < max_length && t < Qss_misc::INF && CUR_SUBSTEP(simulator) < QSS_MAX_SUBSTEPS) {
cf0 = index * coeffs;
elapsed = t - tx[index];
method->advance_time_x(cf0, elapsed);
tx[index] = t;
lqu[index] = dQRel[index] * std::fabs(x[cf0]);
if (lqu[index] < dQMin[index]) {
lqu[index] = dQMin[index];
}
method->update_quantized_state(index);
tq[index] = t;
method->next_time(index, t);
for (G4int i = 0; i < 3; i++) {
G4int j = SD[index][i];
elapsed = t - tx[j];
infCf0 = j * coeffs;
if (elapsed > 0) {
x[infCf0] = method->evaluate_x_poly(infCf0, elapsed, x);
tx[j] = t;
}
}
this->update_field();
this->recompute_derivatives(index);
method->recompute_next_times(SD[index], t);
if (t > prev_time) {
length += fVelocity * (t - prev_time);
if (length <= max_length) { this->save_substep(t, length); }
else { break; }
}
this->update_time();
prev_time = t;
t = simulator->time;
index = simulator->minIndex;
}
if(CUR_SUBSTEP(simulator) >= QSS_MAX_SUBSTEPS) {
max_length = length;
}
auto* const substep = &LAST_SUBSTEP_STRUCT(simulator);
t = substep->start_time + (max_length - substep->len) / fVelocity;
this->get_state_from_poly(substep->x, substep->tx, t, yOut);
velocity_to_momentum(yOut);
const G4int numberOfVariables = GetNumberOfVariables();
for (G4int i = 0; i < numberOfVariables; ++i) {
// Store Input and Final values, for possible use in calculating chord
fyIn[i] = yInput[i];
fyOut[i] = yOut[i];
}
fLastStepLength = max_length;
}
template<class QSS>
inline G4double G4QSStepper<QSS>::DistChord() const
{
G4double yMid[6];
const_cast<G4QSStepper<QSS>*>(this)->Interpolate(0.5, yMid);
const G4ThreeVector begin = makeVector(fyIn, field_utils::Value3D::Position);
const G4ThreeVector end = makeVector(fyOut, field_utils::Value3D::Position);
const G4ThreeVector mid = makeVector(yMid, field_utils::Value3D::Position);
return G4LineSection::Distline(mid, begin, end);
}
template <class QSS>
inline void G4QSStepper<QSS>::Interpolate(G4double tau, G4double yOut[])
{
G4double length = tau * fLastStepLength;
G4int idx = 0, j = LAST_SUBSTEP(simulator);
G4double end_time;
if (j >= 15) {
G4int i = 0, k = j;
idx = j >> 1;
while (idx < k && i < j - 1) {
if (length < SUBSTEP_LEN(simulator, idx)) {
j = idx;
} else if (length >= SUBSTEP_LEN(simulator, idx + 1)) {
i = idx;
} else {
break;
}
idx = (i + j) >> 1;
}
}
else {
for (; idx < j && length >= SUBSTEP_LEN(simulator, idx + 1); idx++) {;}
}
auto* const substep = &SUBSTEP_STRUCT(simulator, idx);
end_time = substep->start_time + (length - substep->len) / fVelocity;
this->get_state_from_poly(substep->x, substep->tx, end_time, yOut);
velocity_to_momentum(yOut);
}
template <class QSS>
inline void G4QSStepper<QSS>::reset(const G4FieldTrack* track)
{
using Qss_misc::PXidx;
using Qss_misc::PYidx;
using Qss_misc::PZidx;
using Qss_misc::VXidx;
using Qss_misc::VYidx;
using Qss_misc::VZidx;
G4ThreeVector pos = track->GetPosition();
G4ThreeVector momentum = track->GetMomentum();
f_mass = track->GetRestMass();
set_charge(track->GetCharge());
set_gamma(momentum.mag2());
G4double c_mg = cLight_local / fMassGamma;
set_velocity(momentum.mag() * c_mg);
method->reset_state(PXidx, pos.getX());
method->reset_state(PYidx, pos.getY());
method->reset_state(PZidx, pos.getZ());
method->reset_state(VXidx, momentum.getX() * c_mg);
method->reset_state(VYidx, momentum.getY() * c_mg);
method->reset_state(VZidx, momentum.getZ() * c_mg);
this->update_field();
method->full_definition(get_coeff());
method->recompute_all_state_times(0);
simulator->time = 0;
}
template <class QSS>
inline void G4QSStepper<QSS>::SetPrecision(G4double dq_rel, G4double dq_min)
{
G4double* dQMin = simulator->dQMin;
G4double* dQRel = simulator->dQRel;
G4int n_vars = simulator->states;
if (dq_min <= 0) { dq_min = dq_rel * 1e-3; }
for (G4int i = 0; i < n_vars; ++i) {
dQRel[i] = dq_rel;
dQMin[i] = dq_min;
}
}
template <class QSS>
inline void G4QSStepper<QSS>::initialize_data_structs()
{
auto sim = this->simulator;
auto states = (G4int*)calloc(Qss_misc::VAR_IDX_END, sizeof(G4int));
sim->states = Qss_misc::VAR_IDX_END;
sim->it = 0.;
for (unsigned int i = 0; i < Qss_misc::VAR_IDX_END; i++) {
sim->SD[i] = (G4int*)malloc(3 * sizeof(G4int));
}
sim->SD[0][states[0]++] = 3;
sim->SD[0][states[0]++] = 4;
sim->SD[0][states[0]++] = 5;
sim->SD[1][states[1]++] = 3;
sim->SD[1][states[1]++] = 4;
sim->SD[1][states[1]++] = 5;
sim->SD[2][states[2]++] = 3;
sim->SD[2][states[2]++] = 4;
sim->SD[2][states[2]++] = 5;
sim->SD[3][states[3]++] = 0;
sim->SD[3][states[3]++] = 4;
sim->SD[3][states[3]++] = 5;
sim->SD[4][states[4]++] = 1;
sim->SD[4][states[4]++] = 3;
sim->SD[4][states[4]++] = 5;
sim->SD[5][states[5]++] = 2;
sim->SD[5][states[5]++] = 3;
sim->SD[5][states[5]++] = 4;
free(states);
}
template <class QSS>
inline QSS_simulator G4QSStepper<QSS>::build_simulator()
{
QSS_simulator sim = (QSS_simulator)malloc(sizeof(*sim));
MAX_SUBSTEP(sim) = Qss_misc::MIN_SUBSTEPS;
SUBSTEPS(sim) = (QSSSubstep)malloc(Qss_misc::MIN_SUBSTEPS * sizeof(*SUBSTEPS(sim)));
return sim;
}
template <class QSS>
inline void G4QSStepper<QSS>::recompute_derivatives(G4int index)
{
const G4int coeffs = method->order() + 1;
G4double e;
G4int idx = 0;
e = simulator->time - simulator->tq[0];
if (likely(e > 0)) { method->advance_time_q(idx, e); }
simulator->tq[0] = simulator->time;
idx += coeffs;
e = simulator->time - simulator->tq[1];
if (likely(e > 0)) { method->advance_time_q(idx, e); }
simulator->tq[1] = simulator->time;
idx += coeffs;
e = simulator->time - simulator->tq[2];
if (likely(e > 0)) { method->advance_time_q(idx, e); }
simulator->tq[2] = simulator->time;
idx += coeffs;
e = simulator->time - simulator->tq[3];
if (likely(e > 0)) { method->advance_time_q(idx, e); }
simulator->tq[3] = simulator->time;
idx += coeffs;
e = simulator->time - simulator->tq[4];
if (likely(e > 0)) { method->advance_time_q(idx, e); }
simulator->tq[4] = simulator->time;
idx += coeffs;
e = simulator->time - simulator->tq[5];
if (likely(e > 0)) { method->advance_time_q(idx, e); }
simulator->tq[5] = simulator->time;
method->dependencies(index, get_coeff());
}
template <class QSS>
inline void G4QSStepper<QSS>::update_field()
{
using Qss_misc::PXidx;
using Qss_misc::PYidx;
using Qss_misc::PZidx;
const G4int order1 = method->order() + 1;
G4double* const _field = simulator->alg;
G4double* const _point = _field + order1;
_point[PXidx] = simulator->x[PXidx];
_point[PYidx] = simulator->x[PYidx * order1];
_point[PZidx] = simulator->x[PZidx * order1];
this->GetEquationOfMotion()->GetFieldValue(_point, _field);
}
template <class QSS>
inline void G4QSStepper<QSS>::save_substep(G4double time, G4double length)
{
memcpy(CUR_SUBSTEP_X(simulator), simulator->x,
(Qss_misc::VAR_IDX_END * (Qss_misc::MAX_QSS_STEPPER_ORDER + 2)) * sizeof(G4double));
CUR_SUBSTEP_START(simulator) = time;
CUR_SUBSTEP_LEN(simulator) = length;
CUR_SUBSTEP(simulator)++;
if (unlikely(CUR_SUBSTEP(simulator) == MAX_SUBSTEP(simulator))) {
this->realloc_substeps();
}
}
template <class QSS>
inline void G4QSStepper<QSS>::realloc_substeps()
{
const G4int prev_index = MAX_SUBSTEP(simulator), new_index = 2 * prev_index;
MAX_SUBSTEP(simulator) = new_index;
SUBSTEPS(simulator) =
(QSSSubstep)realloc(SUBSTEPS(simulator), new_index * sizeof(*SUBSTEPS(simulator)));
}
template <class QSS>
inline void G4QSStepper<QSS>::get_state_from_poly(
G4double* x, G4double* tx, G4double time, G4double* state)
{
unsigned int coeff_index = 0, i;
const unsigned int x_order = method->order(), x_order1 = x_order + 1;
for (i = 0; i < Qss_misc::VAR_IDX_END; ++i) {
assert(tx[i] <= time);
state[i] = method->evaluate_x_poly(coeff_index, time - tx[i], x);
coeff_index += x_order1;
}
}
template <class QSS>
inline void G4QSStepper<QSS>::velocity_to_momentum(G4double* state)
{
using Qss_misc::VXidx;
using Qss_misc::VYidx;
using Qss_misc::VZidx;
G4double coeff = fMassGamma / cLight_local;
state[VXidx] *= coeff;
state[VYidx] *= coeff;
state[VZidx] *= coeff;
}
#include "G4QSStepper.icc"
#endif
@@ -0,0 +1,386 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// G4QSStepper inline methods implementation
//
// Authors - version 1 : Lucio Santi, Rodrigo Castro (Univ. Buenos Aires) - 2018-2021
// - version 2 : Mattias Portnoy (Univ. Buenos Aires) - 2024
// ----------------------------------------------------------------------------
inline
constexpr G4double G4QSStepper::Cubic_Function(const QSStateVector* states,
G4int index, G4double delta_t)
{
return states[DERIVATIVE_0][index] + (states[DERIVATIVE_1][index] + states[DERIVATIVE_2][index] * delta_t / 2 + states[DERIVATIVE_3][index] * delta_t * delta_t / 6) * delta_t;
}
// ----------------------------------------------------------------------------
inline
constexpr G4double G4QSStepper::Parabolic_Function(const QSStateVector* states,
G4int index, G4double delta_t)
{
return states[DERIVATIVE_0][index] + (states[DERIVATIVE_1][index] + states[DERIVATIVE_2][index] * delta_t / 2) * delta_t;
}
// ----------------------------------------------------------------------------
inline
constexpr G4double G4QSStepper::Linear_Function(const QSStateVector* states,
G4int index, G4double delta_t)
{
return states[DERIVATIVE_0][index] + states[DERIVATIVE_1][index] * delta_t;
}
// ----------------------------------------------------------------------------
inline
constexpr G4int G4QSStepper::INDEX_TYPE(G4int i)
{
return i >> 2;
}
// ----------------------------------------------------------------------------
inline
void G4QSStepper::set_qss_order(G4int order)
{
qss_order=order;
}
// ----------------------------------------------------------------------------
inline
void G4QSStepper::momentum_to_velocity(const G4double* momentum, G4double* out)
{
out[0] = momentum[0] * fInv_mass_over_c;
out[1] = momentum[1] * fInv_mass_over_c;
out[2] = momentum[2] * fInv_mass_over_c;
}
// ----------------------------------------------------------------------------
inline
void G4QSStepper::compare_time_and_update(G4int index, G4int i)
{
if (current_substep.sync_t[i] < current_substep.sync_t[index]) { index = i;}
}
// ----------------------------------------------------------------------------
inline
G4int G4QSStepper::IntegratorOrder() const
{
return qss_order;
}
// ----------------------------------------------------------------------------
inline
G4EquationOfMotion* G4QSStepper::GetSpecificEquation()
{
return GetEquationOfMotion();
}
// ----------------------------------------------------------------------------
inline
const field_utils::State& G4QSStepper::GetYOut() const
{
return fYout;
}
// ----------------------------------------------------------------------------
inline
G4double G4QSStepper::DistChord() const
{
return 0.;
}
// ----------------------------------------------------------------------------
inline
void G4QSStepper::Stepper(const G4double yInput[],
const G4double dydx[], G4double hstep,
G4double yOutput[], G4double yError[], G4double /*dydxOutput*/ [])
{
Stepper(yInput, dydx, hstep, yOutput, yError);
}
// ----------------------------------------------------------------------------
inline
void G4QSStepper::SetupInterpolation()
{
}
inline
void G4QSStepper::reset(const G4FieldTrack *track)
{
fTrack_changed = true; //// Cannot rely on addresses --- OLD was track != fCurrent_track;
fCurrent_track = track;
}
// ----------------------------------------------------------------------------
inline
void G4QSStepper::SetPrecision(G4double dq_rel, G4double dq_min)
{
dqmin[0] = dq_min;
dqmin[1] = dq_min;
dqrel[0] = dq_rel;
dqrel[1] = dq_rel;
}
// ----------------------------------------------------------------------------
inline
G4double G4QSStepper::GetLastStepLength()
{
return current_substep.t * fVelocity;
}
// ----------------------------------------------------------------------------
inline
void G4QSStepper::velocity_to_momentum(G4double *y)
{
y[3] *= fMassOverC;
y[4] *= fMassOverC;
y[5] *= fMassOverC;
}
// ----------------------------------------------------------------------------
inline
G4int G4QSStepper::get_next_sync_index()
{
// Goes through each index and get the one with the closest sync t.
// Unrolled loop for tiny speedup.
G4int index = 0;
compare_time_and_update(index,1);
compare_time_and_update(index,2);
compare_time_and_update(index,3);
compare_time_and_update(index,4);
compare_time_and_update(index,5);
return index;
}
// ----------------------------------------------------------------------------
inline
void G4QSStepper::update_field()
{
G4double old_field[3] = { current_substep.b_field[0],
current_substep.b_field[1],
current_substep.b_field[2] };
GetEquationOfMotion()->GetFieldValue(current_substep.state_x[DERIVATIVE_0],
current_substep.b_field );
fField_changed = false;
for (G4int i = 0; i < 3 && ! fField_changed; ++i)
{
fField_changed = fField_changed || old_field[i] != current_substep.b_field[i];
}
}
// ----------------------------------------------------------------------------
inline
G4double G4QSStepper::extrapolate_polynomial(QSStateVector* states,
G4int index, G4double delta_t, G4int order)
{
if (delta_t == 0 || order == 0) { return states[DERIVATIVE_0][index]; }
switch (order)
{
case 2:
return Parabolic_Function(states,index,delta_t);
break;
case 3:
return Cubic_Function(states,index,delta_t);
break;
case 1:
return Linear_Function(states,index,delta_t);
break;
default:
// TODO check how to raise error
return 146546;
}
}
// ----------------------------------------------------------------------------
inline
void G4QSStepper::extrapolate_all_states_to_t(Substep* substep,
G4double t, G4double* yOut)
{
for (G4int j = 0; j < 6; ++j)
{
G4double t_j = substep->state_tx[j];
G4double delta_tj = t - t_j;
yOut[j] = extrapolate_polynomial(&substep->state_x[DERIVATIVE_0], j, delta_tj, substep->extrapolation_method);
}
}
// ----------------------------------------------------------------------------
inline
void G4QSStepper::update_x(G4int index, G4double t)
{
G4double delta_t = t - current_substep.state_tx[index];
if (delta_t == 0) { return; }
//current_substep.state_x[DERIVATE_1][index] += current_substep.state_x[DERIVATE_2][index] * delta_t;
switch (qss_order)
{
case 2:
current_substep.state_x[DERIVATIVE_0][index] = Parabolic_Function(current_substep.state_x,index,delta_t);
current_substep.state_x[DERIVATIVE_1][index] = Linear_Function((&current_substep.state_x[DERIVATIVE_1]),index,delta_t);
break;
case 3:
current_substep.state_x[DERIVATIVE_0][index] = Cubic_Function(current_substep.state_x,index,delta_t);
current_substep.state_x[DERIVATIVE_1][index] = Parabolic_Function((&current_substep.state_x[DERIVATIVE_1]),index,delta_t);
current_substep.state_x[DERIVATIVE_2][index] = Linear_Function((&current_substep.state_x[DERIVATIVE_2]),index,delta_t);
break;
case 1:
current_substep.state_x[DERIVATIVE_0][index] = Linear_Function(current_substep.state_x,index,delta_t);
break;
default:
break;
}
current_substep.state_tx[index] = t;
}
// ----------------------------------------------------------------------------
inline
void G4QSStepper::update_q(G4int index, G4double t)
{
G4double delta_t = t - current_substep.state_tq[index];
if (delta_t == 0) { return; }
switch (qss_order)
{
case 2:
current_substep.state_q[DERIVATIVE_0][index] = Linear_Function(current_substep.state_q,index,delta_t);
break;
case 3:
current_substep.state_q[DERIVATIVE_0][index] = Parabolic_Function(current_substep.state_q,index,delta_t);
current_substep.state_q[DERIVATIVE_1][index] = Linear_Function((&current_substep.state_q[DERIVATIVE_1]),index,delta_t);
break;
case 1:
break;
}
current_substep.state_tq[index] = t;
}
// ----------------------------------------------------------------------------
inline
void G4QSStepper::update_x_position_derivates_using_q(G4int index)
{
// assumes index is position index
current_substep.state_x[DERIVATIVE_1][index] =
current_substep.state_q[DERIVATIVE_0][index+VELOCITY_IDX];
current_substep.state_x[DERIVATIVE_2][index] =
current_substep.state_q[DERIVATIVE_1][index+VELOCITY_IDX];
current_substep.state_x[DERIVATIVE_3][index] =
current_substep.state_q[DERIVATIVE_2][index+VELOCITY_IDX];
}
// ----------------------------------------------------------------------------
inline
void G4QSStepper::update_x_velocity_derivates_using_q(G4int index)
{
// asumes index is velocity index
G4int modulo = VELOCITY_IDX;
G4int index_pos = (index+modulo+1)%modulo;
G4int index_neg = (index+modulo-1)%modulo;
G4double b1 = current_substep.b_field[index_pos];
G4double b2 = current_substep.b_field[index_neg];
for (G4int derivate_order = 0; derivate_order < qss_order; ++derivate_order)
{
current_substep.state_x[derivate_order+1][index] =
fCoeff* (
current_substep.state_q[derivate_order][index_pos+VELOCITY_IDX] * b2 -
current_substep.state_q[derivate_order][index_neg+VELOCITY_IDX] * b1
);
}
}
// ----------------------------------------------------------------------------
inline
void G4QSStepper::update_x_derivates_using_q(G4int index)
{
// updates x using q with the Lorentz equation
if (index < VELOCITY_IDX)
{
update_x_position_derivates_using_q(index);
}
else
{
update_x_velocity_derivates_using_q(index);
}
}
// ----------------------------------------------------------------------------
/* Updates when does the x,q distance goes beyond the quantum.
For the special case of both polynomials being equal except
for higher coefficient- Such as after syncing */
inline
void G4QSStepper::update_sync_time_one_coefficient(G4int index)
{
G4double leading_poly_cofficient = current_substep.state_x[qss_order][index];
if (leading_poly_cofficient == 0)
{
current_substep.sync_t[index] = INFTY;
}
else
{
G4double dq_leading_ratio = dq_vector[index]/fabs(leading_poly_cofficient);
switch (qss_order)
{
case 2:
current_substep.sync_t[index] = current_substep.state_tx[index] + sqrt(dq_leading_ratio);
break;
case 3:
current_substep.sync_t[index] = current_substep.state_tx[index] + cbrt(dq_leading_ratio);
break;
case 1:
current_substep.sync_t[index] = current_substep.state_tx[index] + dq_leading_ratio;
break;
}
}
}
@@ -0,0 +1,107 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Structs used by G4QSStepper
//
// Author: Mattias Portnoy (Univ. Buenos Aires) - 2024
// --------------------------------------------------------------------
#ifndef G4QSS_SUBSTEPSTRUCT_HH
#define G4QSS_SUBSTEPSTRUCT_HH 1
#include "G4FieldTrack.hh"
#include "G4MagIntegratorStepper.hh"
#include "G4qss_misc.hh"
#include <map>
#include <cmath>
constexpr G4int MAX_QSS_ORDER=3;
typedef G4double QSStateVector[6];
struct Substep
{
QSStateVector state_x[MAX_QSS_ORDER+1];
QSStateVector state_q[MAX_QSS_ORDER];
QSStateVector state_tx;
QSStateVector state_tq;
QSStateVector sync_t;
G4double t;
// simple id method so that substeps can have different orders in same step
G4int extrapolation_method;
G4double b_field[3];
};
struct Substeps
{
G4int _arrlength = 30;
Substep* _substeps = static_cast<Substep *>(malloc((_arrlength) * sizeof(Substep)));
G4int current_substep_index = -1;
// Mimics the functionality of GNU method reallocarray
void* safe_reallocarray(void* ptr, size_t numMembers, size_t size)
{
if (size != 0 && numMembers > std::numeric_limits<size_t>::max() / size)
{
return nullptr;
}
return realloc(ptr, numMembers * size);
}
inline void resize()
{
_arrlength = fmax(_arrlength*2, 1500);
_substeps = static_cast<Substep *>(safe_reallocarray(_substeps, _arrlength, sizeof(Substep)));
if( _substeps == nullptr )
{
G4ExceptionDescription ermsg;
ermsg << "QSS2: Size of state exceed available memory : number of elemets = " << _arrlength
<< " size of each element= " << sizeof(Substep) << G4endl;
G4Exception( "G4QSSubstepStruct::resize", "GeomField0008", FatalException, ermsg );
}
}
inline Substep* create_susbtep()
{
current_substep_index++;
if (unlikely( current_substep_index >= _arrlength ))
{
resize();
}
return &(_substeps[current_substep_index]);
}
inline void save_substep(Substep* substep)
{
memcpy(create_susbtep(), substep, sizeof(Substep));
}
inline void reset()
{
current_substep_index = -1;
}
};
#endif
+3 -3
View File
@@ -125,13 +125,14 @@ geant4_add_module(G4magneticfield
# QSS - headers
G4QSSDriver.hh
G4QSSDriver.icc
G4QSSDriverCreator.hh
G4QSStepper.hh
G4QSStepper.icc
G4QSS2.hh
G4QSS3.hh
G4QSS_CustomStats.hh
G4qss_misc.hh
G4QSSMessenger.hh
G4QSSubstepStruct.hh
SOURCES
G4BFieldIntegrationDriver.cc
G4BogackiShampine23.cc
@@ -197,7 +198,6 @@ geant4_add_module(G4magneticfield
G4NystromRK4.cc
G4OldMagIntDriver.cc
G4QuadrupoleMagField.cc
G4QSSDriverCreator.cc
G4RepleteEofM.cc
G4RKG3_Stepper.cc
G4RK547FEq1.cc
@@ -226,4 +226,4 @@ geant4_module_include_directories(G4magneticfield PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/source/particles/management/include>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/source/intercoms/include>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/source/track/include>
)
)
@@ -62,7 +62,9 @@
#include "G4HelixHeum.hh"
#include "G4BFieldIntegrationDriver.hh"
#include "G4QSSDriverCreator.hh"
#include "G4QSStepper.hh"
#include "G4QSSDriver.hh"
#include "G4AutoDelete.hh"
#include "G4CachedMagneticField.hh"
@@ -303,27 +305,19 @@ G4ChordFinder::G4ChordFinder( G4MagneticField* theMagField,
}
else if( useG4QSSDriver )
{
if( stepperDriverId == kQss2DriverType )
if (stepperDriverId == kQss2DriverType)
{
auto qssStepper2 = G4QSSDriverCreator::CreateQss2Stepper(pEquation);
if( gVerboseCtor )
{
G4cout << "-- Created QSS-2 stepper" << G4endl;
}
fIntgrDriver = G4QSSDriverCreator::CreateDriver(qssStepper2);
}
else
{
auto qssStepper3 = G4QSSDriverCreator::CreateQss3Stepper(pEquation);
if( gVerboseCtor )
{
G4cout << "-- Created QSS-3 stepper" << G4endl;
}
fIntgrDriver = G4QSSDriverCreator::CreateDriver(qssStepper3);
fQssStepperOwned= new G4QSStepper(pEquation);
auto qss_driver = new G4QSSDriver<G4QSStepper>(fQssStepperOwned);
if( gVerboseCtor )
{
G4cout << "-- Created QSS-2 stepper" << G4endl;
}
fIntgrDriver = qss_driver;
}
if( gVerboseCtor )
{
G4cout << "-- G4ChordFinder: Using QSS Driver." << G4endl;
G4cout << "-- G4ChordFinder: Using QSS Driver." << G4endl;
}
}
else
@@ -417,6 +411,7 @@ G4ChordFinder::~G4ChordFinder()
delete fEquation;
delete fRegularStepperOwned;
delete fNewFSALStepperOwned;
delete fQssStepperOwned;
delete fCachedField;
delete fIntgrDriver;
}
@@ -1,108 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// G4QSSDriverCreator implementation
//
// Author: J.Apostolakis (CERN) - 2021-2023
// --------------------------------------------------------------------
#include "G4QSSDriverCreator.hh"
#include "G4MagIntegratorStepper.hh"
#include "G4VIntegrationDriver.hh"
#include "G4QSSDriver.hh"
#include "G4QSStepper.hh"
#include "G4QSS2.hh"
#include "G4QSS3.hh"
#include "G4Mag_UsualEqRhs.hh"
#include <cassert>
G4VIntegrationDriver*
G4QSSDriverCreator::CreateDriver( G4MagIntegratorStepper* pStepper, G4double /*stepMin*/ )
{
G4VIntegrationDriver* driver = nullptr;
// pStepper->build_driver(stepMinimum, true); // Original - QSS
auto qss2stepper = dynamic_cast<G4QSStepper<G4QSS2>*>(pStepper);
if( qss2stepper != nullptr ) {
// driver = new G4QSSDriver<G4QSStepper<G4QSS2>>(qss2stepper);
driver = CreateDriver( qss2stepper );
}
auto qss3stepper = dynamic_cast<G4QSStepper<G4QSS3>*>(pStepper);
if( qss3stepper != nullptr ) {
// driver = new G4QSSDriver<G4QSStepper<G4QSS3>>(qss3stepper);
driver= CreateDriver( qss3stepper );
}
return driver;
}
G4QSSDriver<G4QSStepper<G4QSS2>>*
G4QSSDriverCreator::CreateDriver( G4QSStepper<G4QSS2>* qss2stepper )
{
G4cout << "---- G4QSSDriver<G4QSS2>* G4QSSDriverCreator::CreateDriver(G4QSStepper<G4QSS2>* ) called.\n";
return new G4QSSDriver<G4QSStepper<G4QSS2>>(qss2stepper);
}
static constexpr G4int numOfVars= 6;
G4QSSDriver<G4QSStepper<G4QSS3>>*
G4QSSDriverCreator::CreateDriver( G4QSStepper<G4QSS3>* qss3stepper )
{
G4cout << "---- G4QSSDriver<G4QSS3>* G4QSSDriverCreator::CreateDriver(G4QSStepper<G4QSS3>* ) called.\n";
return new G4QSSDriver<G4QSStepper<G4QSS3>>(qss3stepper);
}
G4QSStepper<G4QSS2>* G4QSSDriverCreator::G4QSSDriverCreator::CreateQss2Stepper(G4Mag_EqRhs* Equation)
{
G4cout << "---- G4QSStepper<G4QSS2>* CreateQss2Stepper(G4Mag_EqRhs* ) CALLED\n";
return G4QSStepper<G4QSS2>::build_QSS2( Equation, numOfVars, true);
}
G4QSStepper<G4QSS3>* G4QSSDriverCreator::CreateQss3Stepper(G4Mag_EqRhs* Equation)
{
G4cout << "---- G4QSStepper<G4QSS3>* CreateQss3Stepper(G4Mag_EqRhs* ) CALLED\n";
return G4QSStepper<G4QSS3>::build_QSS3( Equation, numOfVars, true);
}
G4VIntegrationDriver* G4QSSDriverCreator::CreateQss2Driver(G4Mag_EqRhs* Equation)
{
assert( dynamic_cast<G4Mag_UsualEqRhs*>(Equation) != nullptr );
// assert( Equation->GetNumberOfVariables() == numOfVars );
auto qss2stepper = G4QSStepper<G4QSS2>::build_QSS2( Equation, numOfVars, true);
return CreateDriver( qss2stepper );
}
G4VIntegrationDriver* G4QSSDriverCreator::
CreateQss3Driver(G4Mag_EqRhs *Equation)
{
assert( dynamic_cast<G4Mag_UsualEqRhs*>(Equation) != nullptr );
// assert( Equation->GetNumberOfVariables() == numOfVars );
auto qss3stepper = G4QSStepper<G4QSS3>::build_QSS3( Equation, numOfVars, true);
return CreateDriver( qss3stepper );
}
@@ -55,6 +55,11 @@ G4QSSMessenger::G4QSSMessenger()
stepperSelectorCmd->SetParameterName("choice", false);
stepperSelectorCmd->SetCandidates("TemplatedDoPri OldRK45 G4QSS2");
maxSubstepsCmd = new G4UIcmdWithAnInteger("/QSS/maxSubsteps",this);
maxSubstepsCmd->SetGuidance("Default is 5000");
maxSubstepsCmd->SetDefaultValue(5000);
maxSubstepsCmd->SetParameterName("maxSubstepsCmd", false);
}
G4QSSMessenger::~G4QSSMessenger()
@@ -64,6 +69,7 @@ G4QSSMessenger::~G4QSSMessenger()
delete dQRelCmd;
delete stepperSelectorCmd;
delete trialProposedStepModifierCmd;
delete maxSubstepsCmd;
//qssStats.print();
}
@@ -83,6 +89,10 @@ void G4QSSMessenger::SetNewValue(G4UIcommand *command, G4String newValue)
dQRel = dQRelCmd->GetNewDoubleValue(newValue);
}
if (command == maxSubstepsCmd){
maxSubsteps = maxSubstepsCmd->GetNewIntValue(newValue);
}
if ( command == trialProposedStepModifierCmd ) {
trialProposedStepModifier = trialProposedStepModifierCmd->GetNewDoubleValue(newValue);
}
+378 -25
View File
@@ -22,44 +22,397 @@
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// G4QSStepper implementation
//
// Authors: Lucio Santi, Rodrigo Castro (Univ. Buenos Aires) - 2018-2021
// G4QSStepper
//
// QSS Integrator Stepper
//
// Authors - version 1 : Lucio Santi, Rodrigo Castro (Univ. Buenos Aires) - 2018-2021
// - version 2 : Mattias Portnoy (Univ. Buenos Aires) - 2024
// --------------------------------------------------------------------
#include "G4QSStepper.hh"
#include "G4PhysicalConstants.hh"
template<>
G4QSStepper_QSS3::G4QSStepper(G4EquationOfMotion *EqRhs,
G4int numberOfVariables,
G4bool primary)
: G4QSStepper(new G4QSS3(G4QSStepper_QSS3::build_simulator()),
EqRhs, numberOfVariables, primary)
// ----------------------------------------------------------------------------
G4QSStepper::G4QSStepper( G4EquationOfMotion* equation,
G4int num_integration_vars,
G4int num_state_vars,
G4bool isFSAL,
G4int /*verbosity*/ ):
G4MagIntegratorStepper(equation,num_integration_vars,num_state_vars,isFSAL)
{
using std::memset;
set_qss_order(G4QSSMessenger::instance()->QssOrder);
SetIsQSS(true);
for (G4int i = 0; i < MAX_QSS_ORDER-1; ++i)
{
memset(&current_substep.state_x[i], 0, sizeof(QSStateVector));
memset(&current_substep.state_q[i], 0, sizeof(QSStateVector));
}
memset(&current_substep.state_x[MAX_QSS_ORDER-1], 0, sizeof(QSStateVector));
current_substep.b_field[0] = 0.0;
current_substep.b_field[1] = 0.0;
current_substep.b_field[2] = 0.0;
}
// ----------------------------------------------------------------------------
G4QSStepper::G4QSStepper(G4EquationOfMotion *EqRhs,
G4int numberOfVariables,
G4bool primary)
: G4QSStepper(EqRhs,numberOfVariables, numberOfVariables, primary)
{
}
template<>
G4QSStepper_QSS2::G4QSStepper(G4EquationOfMotion *EqRhs,
G4int numberOfVariables,
G4bool primary)
: G4QSStepper(new G4QSS2(G4QSStepper_QSS2::build_simulator()),
EqRhs, numberOfVariables, primary)
// ----------------------------------------------------------------------------
G4QSStepper::~G4QSStepper()
{
free(substeps._substeps);
}
template<>
G4QSStepper_QSS2 *G4QSStepper_QSS2::build_QSS2(G4EquationOfMotion *EqRhs,
G4int noIntegrationVariables,
G4bool primary)
// ----------------------------------------------------------------------------
void G4QSStepper::set_relativistic_coeff(const G4double* momentum)
{
return new G4QSStepper<G4QSS2>(EqRhs, noIntegrationVariables, primary);
G4double momentum2 = momentum[0]*momentum[0] + momentum[1]*momentum[1] + momentum[2]*momentum[2];
fGamma = sqrt(momentum2/(fRestMass*fRestMass) + 1);
G4double mass_times_gamma = fRestMass * fGamma;
fMassOverC = mass_times_gamma * (1.0 / CLHEP::c_light);
fInv_mass_over_c = CLHEP::c_light * (1.0 / mass_times_gamma);
fCoeff = fCharge_c2 / mass_times_gamma;
}
template<>
G4QSStepper_QSS3 *G4QSStepper_QSS3::build_QSS3(G4EquationOfMotion *EqRhs,
G4int noIntegrationVariables,
G4bool primary)
// ----------------------------------------------------------------------------
void G4QSStepper::initialize(const G4double y[])
{
return new G4QSStepper<G4QSS3>(EqRhs, noIntegrationVariables, primary);
using std::memcpy;
using std::memset;
substeps.reset();
// OLD: if (track_change && fCurrent_track != nullptr) {
// Cannot rely on detecting an address change -> always load values!
if (fCurrent_track != nullptr)
{
fCharge = fCurrent_track->GetCharge();
fCharge_c2 = fCharge * 89875.5178737;
fRestMass = fCurrent_track->GetRestMass();
}
// y contains postion in first 3 index and momentum on the next 3
set_relativistic_coeff(&y[3]);
G4double velocity_vector[3];
momentum_to_velocity(&y[3], velocity_vector);
fVelocity = sqrt(velocity_vector[0]*velocity_vector[0] + velocity_vector[1]*velocity_vector[1] + velocity_vector[2]*velocity_vector[2] );
memcpy(
&current_substep.state_x[DERIVATIVE_0][POSITION_IDX],
y,
sizeof(G4double) * 3
);
memcpy(
&current_substep.state_x[DERIVATIVE_0][VELOCITY_IDX],
&velocity_vector,
sizeof(G4double) * 3
);
memcpy(
&current_substep.state_q[DERIVATIVE_0],
&current_substep.state_x[DERIVATIVE_0],
sizeof(QSStateVector)
);
for (G4int i = 1; i < qss_order; ++i)
{
std::fill_n(current_substep.state_q[i], NUMBER_OF_VARIABLES_QSS, 0.0);
}
std::fill_n(current_substep.state_tx, NUMBER_OF_VARIABLES_QSS, 0.0);
std::fill_n(current_substep.state_tq, NUMBER_OF_VARIABLES_QSS, 0.0);
current_substep.t = 0;
current_substep.extrapolation_method = qss_order;
update_field();
for (G4int i = 0; i < NUMBER_OF_VARIABLES_QSS; ++i)
{
dq_vector[i] = fmax(dqmin[INDEX_TYPE(i)], dqrel[INDEX_TYPE(i)] * fabs(current_substep.state_x[DERIVATIVE_0][i]));
update_x_derivates_using_q(i);
update_sync_time(i);
}
}
// ----------------------------------------------------------------------------
void G4QSStepper::update_sync_time(G4int index)
{
G4double &dq = dq_vector[index];
G4double delta_sync_t = INFTY;
// polynomial coefficients in increasing order of power, constant, linear, quadratic, etc
G4double c, b, a, h;
a = current_substep.state_x[DERIVATIVE_2][index]/2;
b = current_substep.state_x[DERIVATIVE_1][index] - current_substep.state_q[DERIVATIVE_1][index] ;
c = current_substep.state_x[DERIVATIVE_0][index] - current_substep.state_q[DERIVATIVE_0][index];
// third order polynomial. It's a long algorithm but not a complex one
if (qss_order == 3 && current_substep.state_x[DERIVATIVE_3][index] != 0.0)
{
// extra coefficient and h for the cubic polynomial and inclusion of the second order term from q
h = current_substep.state_x[DERIVATIVE_3][index]/6;
a -= current_substep.state_q[DERIVATIVE_2][index]/2;
G4double q_cube = fCharge*fCharge*fCharge;
// special case of | h * t3 | = dq
if (a == 0 && b == 0 && c == 0)
{
delta_sync_t = cbrt(fabs(dq/h));
}
else
{
a /= h;
b /= h;
c /= h;
G4double qLocal = (a * a - 3 * b) * (1.0 / 9.0);
G4double r_base = (2*a*a*a - 9*a*b + 27*c)*(1.0/54.0);
G4double sqrt_q = sqrt(qLocal);
G4double sqrt_q_cube = sqrt(q_cube);
G4double a_over_3 = a/3;
for (G4double dQ : {dq,-dq})
{
G4double r = r_base + dQ/(2*h);
// three real roots
if (r*r < q_cube)
{
G4double theta = acos(r/sqrt_q_cube);
G4double t1 = -2*sqrt_q*cos((1./3.)*theta) - a_over_3;
G4double t2 = -2*sqrt_q*cos((1./3.)*(theta+2*CLHEP::pi)) - a_over_3;
G4double t3 = -2*sqrt_q*cos((1./3.)*(theta-2*CLHEP::pi)) - a_over_3;
for (G4double t : {t1,t2,t3})
{
if (t > 0) { delta_sync_t = fmin(delta_sync_t,t); }
}
}
// one real root
else
{
G4double A = -copysign(1,r) * cbrt(fabs(r) + sqrt(r*r - q_cube));
G4double B = A == 0 ? 0 : qLocal/A;
G4double t1 = A + B - a_over_3;
if (t1 > 0) {delta_sync_t = fmin(delta_sync_t,t1);}
}
}
}
}
// first order polynomial
else if (qss_order == 1 || a == 0)
{
// dq = | b * t + c |
if (b == 0) { delta_sync_t = INFTY; }
// (dq-c)/b > 0 <--> (b > 0 && dq > c) || (b < 0 && dq < c)
// so we use dq if any of the cases holds and -dq if not
else if ( (b > 0) == (dq > c) ) { delta_sync_t = (dq-c)/b; }
else { delta_sync_t = (-dq-c)/b; }
}
// second order polynomial
else {
if (b == 0) {
// dq = | a_x * t2 + c |
// identical to first order case but with sqrt
if ((a > 0) == (dq > c)) {delta_sync_t = sqrt((dq-c)/a);}
else {delta_sync_t = sqrt((-dq-c)/a);}
}
else
{
// check both discriminants for both dq and - dq
G4double a4 = 4*a;
G4double a2 = 2*a;
G4double discriminator_base = b*b - a4*c;
G4double discriminator_difference = a4*dq;
G4double discriminator_1 = discriminator_base + discriminator_difference;
G4double discriminator_2 = discriminator_base - discriminator_difference;
G4double fixed_solution_part = -b/a2;
// simple trick to combine answers from all 4 solutions
for(G4double discriminator : {discriminator_1, discriminator_2})
{
if (discriminator < 0) { continue; }
G4double variable_solution_part = sqrt(discriminator)/fabs(a2);
G4double t_local = fixed_solution_part - variable_solution_part;
if (t_local <= 0 )
{
t_local = fixed_solution_part + variable_solution_part;
}
if (t_local > 0) { delta_sync_t = fmin(delta_sync_t,t_local); }
}
}
}
current_substep.sync_t[index] = current_substep.state_tx[index] + delta_sync_t;
}
// ----------------------------------------------------------------------------
void G4QSStepper::Stepper( const G4double y[],
const G4double /*dydx*/ [],
G4double h,
G4double yout[],
G4double /* yerr */ [] )
{
using std::memcpy;
initialize(y);
const G4int QSS_MAX_SUBSTEPS = G4QSSMessenger::instance()->maxSubsteps;
G4double t = 0;
fFinal_t = h/fVelocity;
fFinal_t = fmin(fFinal_t,INFTY);
while (t < fFinal_t && t < INFTY && substeps.current_substep_index < QSS_MAX_SUBSTEPS)
{
substeps.save_substep(&current_substep);
// get minimum that makes some variable get too far from its quantized version
G4int sync_index = get_next_sync_index();
t = current_substep.sync_t[sync_index];
t = fmin(t,fFinal_t);
current_substep.t = t;
// sync both and update their data
// update x
update_x(sync_index,t);
// sync q
current_substep.state_q[DERIVATIVE_0][sync_index] = current_substep.state_x[DERIVATIVE_0][sync_index];
current_substep.state_q[DERIVATIVE_1][sync_index] = current_substep.state_x[DERIVATIVE_1][sync_index];
current_substep.state_q[DERIVATIVE_2][sync_index] = current_substep.state_x[DERIVATIVE_2][sync_index];
current_substep.state_tq[sync_index] = current_substep.state_tx[sync_index];
dq_vector[sync_index] = fmax(dqmin[INDEX_TYPE(sync_index)], dqrel[INDEX_TYPE(sync_index)] * fabs(current_substep.state_x[DERIVATIVE_0][sync_index]));
// Somehow this seems to be faster than the one below
update_sync_time(sync_index);
// the trick belows work but seems to be slower
//update_sync_time_one_coefficient(sync_index);
// only update field if we actually changed position, not velocity
// previous version called this every time which is unnecessary if field constant, and we bite the bullet if not
if (sync_index < VELOCITY_IDX) { update_field(); }
// we need to update the affected derivates of the other states
G4double &tIndex = current_substep.state_tx[sync_index];
// if we update position but magnetic field hasn't change then no other variables are affected!
if(sync_index < VELOCITY_IDX && ! fField_changed) { continue; }
// as qs are in different ts, we need to extrapolate the needed qs
// we always need to extrapolate the velocity ones (because the lorentz equation)
update_q(VX,tIndex);
update_q(VY,tIndex);
update_q(VZ,tIndex);
// check which equations are altered by this update according to lorentz eq
// b-field changed, need to update velocity states derivates
if (sync_index < VELOCITY_IDX)
{
for (G4int i = VELOCITY_IDX; i < 6; ++i)
{
update_x(i,tIndex);
update_x_velocity_derivates_using_q(i);
update_sync_time(i);
}
}
// velocity changed, need the other velocity states derivates and the corresponding position one
else
{
G4int indexDep1 = (sync_index + 2)%VELOCITY_IDX + VELOCITY_IDX;
G4int indexDep2 = (sync_index + 1)%VELOCITY_IDX + VELOCITY_IDX;
G4int index_class = sync_index - VELOCITY_IDX;
update_q(index_class,tIndex); // not updated before so we need to update it
for (G4int i : {indexDep1, indexDep2, index_class})
{
update_x(i,tIndex);
update_x_derivates_using_q(i);
update_sync_time(i);
}
}
}
if(substeps.current_substep_index >= QSS_MAX_SUBSTEPS)
{
fFinal_t = current_substep.t;
}
for (G4int i = 0; i < NUMBER_OF_VARIABLES_QSS; ++i)
{
update_x(i, fFinal_t);
}
memcpy(yout, &current_substep.state_x[DERIVATIVE_0], sizeof(QSStateVector));
velocity_to_momentum(yout);
// fyout is used by interpolation driver, so we have to do this
memcpy(fYout,yout,NUMBER_OF_VARIABLES_QSS*sizeof(G4double));
}
// ----------------------------------------------------------------------------
void G4QSStepper::Interpolate(G4double tau,G4double yOut[])
{
G4double target_t = current_substep.t * tau;
G4int i = 0;
G4double t = current_substep.t * tau;;
// linear search
if (substeps.current_substep_index < 20)
{
while(i < substeps.current_substep_index && substeps._substeps[i+1].t <= target_t )
{
i++;
}
}
// binary search
else
{
G4int high_i = substeps.current_substep_index;
G4int low_i = 0;
G4int idx = high_i >> 1;
while(low_i < high_i-1)
{
if(target_t < substeps._substeps[idx].t)
{
high_i = idx;
}
else
{
low_i = idx;
}
idx = (low_i+high_i) >> 1;
}
i = low_i;
}
extrapolate_all_states_to_t(&substeps._substeps[i], t, yOut);
velocity_to_momentum(yOut);
}
+22 -5
View File
@@ -6,29 +6,46 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-03-29 Gabriele Cosmo (geommng-V11-02-08)
## 2025-03-29 Gabriele Cosmo (geommng-V11-03-08)
- In G4GeometryManager, removed redundant declaration of method
ChooseSequentialOptimisation().
## 2025-03-05 Gabriele Cosmo (geommng-V11-02-07)
## 2025-03-24 Evgueni Tcherniaev (geommng-V11-03-07)
- G4VSolid: Set seed in EvaluateCubicVolume() and EvaluateSurfaceArea() to
ensure reproducibility of the resulting value.
## 2025-03-05 Gabriele Cosmo (geommng-V11-03-06)
- Applied clang-tidy to G4GeometryManager and some code cleanup.
Moved additional checks/warnings under verbosity level.
- Additional readability clang-tidy fixes to code.
## 2025-03-03 Gabriele Cosmo
## 2025-03-03 Gabriele Cosmo (geommng-V11-03-05)
- In G4VSolid::EstimateCubicVolume(..), initialise local variable to zero
to silence invalid false positive warnings reported in compilation of CMSSW.
## 2025-02-25 John Apostolakis
## 2025-02-25 John Apostolakis (geommng-V11-03-04)
- Enabled voxelisation parallelism by default in G4GeometryManager, when
MT/tasks are enabled. Enabled also for potential 2nd (and later) calls.
- In G4GeometryManager, fix in ConfigureParallelOptimisation() to reset
logical volumes iterator; in ReportWorkerIsDoneOptimising(), added checks
to report fatal error if incorrect number of volumes was voxelised, and warns
if number of workers reporting is not as expected.
In ConfigureParallelOptimisation(), reports on the times it was called.
## 2025-02-03 Gabriele Cosmo
## 2025-02-20 Gabriele Cosmo (geommng-V11-03-03)
- Applied clang-tidy fixes fixes (readability, modernization, performance, ...)
based on llvm version 19.1.17.
## 2025-02-03 Gabriele Cosmo (geommng-V11-03-02)
- G4UAdapter: removed fake default constructor, clearing compilation warnings
on gcc-14.
## 2025-01-24 Evgueni Tcherniaev (geommng-V11-03-01)
- G4GeomTools: added HyperboloidSurfaceArea()
## 2025-01-05 Evgueni Tcherniaev (geommng-V11-03-00)
- G4GeomTools: added HypeStereo() and TwistedTubeBoundingTrap()
## 2024-08-26 Gabriele Cosmo (geommng-V11-02-06)
- G4GeometryManager: temporarily disable default parallel optimisation.
Fixed spelling for method OptimiseInParallel(..).
@@ -393,7 +393,7 @@ G4double G4AffineTransform::operator [] (const G4int n) const
inline
G4bool G4AffineTransform::IsRotated() const
{
return !(rxx==1.0 && ryy==1.0 && rzz==1.0);
return rxx!=1.0 || ryy!=1.0 || rzz!=1.0;
}
inline
@@ -47,7 +47,7 @@ class G4GeomTools
public:
// ==================================================================
// 2D Utilities
// 2D Utilities
// ------------------------------------------------------------------
static G4double TriangleArea(G4double Ax, G4double Ay,
@@ -108,11 +108,11 @@ class G4GeomTools
std::vector<G4int>& iout,
G4double tolerance = 0.0);
// Remove collinear and coincident points from 2D polygon.
// Indices of removed points are available in iout.
// Indices of removed points are available in iout.
static G4bool DiskExtent(G4double rmin, G4double rmax,
G4double startPhi, G4double delPhi,
G4TwoVector& pmin, G4TwoVector& pmax);
G4TwoVector& pmin, G4TwoVector& pmax);
// Calculate bounding rectangle of a disk sector,
// it returns false if input parameters do not meet the following:
// rmin >= 0
@@ -122,7 +122,7 @@ class G4GeomTools
static void DiskExtent(G4double rmin, G4double rmax,
G4double sinPhiStart, G4double cosPhiStart,
G4double sinPhiEnd, G4double cosPhiEnd,
G4TwoVector& pmin, G4TwoVector& pmax);
G4TwoVector& pmin, G4TwoVector& pmax);
// Calculate bounding rectangle of a disk sector,
// faster version without check of parameters
@@ -136,7 +136,7 @@ class G4GeomTools
// Compute the lateral surface area of an elliptic cone
// ==================================================================
// 3D Utilities
// 3D Utilities
// ------------------------------------------------------------------
static G4ThreeVector TriangleAreaNormal(const G4ThreeVector& A,
@@ -187,7 +187,7 @@ class G4GeomTools
static G4bool SphereExtent(G4double rmin, G4double rmax,
G4double startTheta, G4double delTheta,
G4double startPhi, G4double delPhi,
G4ThreeVector& pmin, G4ThreeVector& pmax);
G4ThreeVector& pmin, G4ThreeVector& pmax);
// Calculate bounding box of a spherical sector,
// it returns false if input parameters do not meet the following:
// rmin >= 0
@@ -196,6 +196,28 @@ class G4GeomTools
// delTheta > 0 + kCarTolerance
// delPhi > 0 + kCarTolerance
static G4double HypeStereo(G4double r0, // radius at z = 0
G4double r, // radius at z = h
G4double h);
// Calculate hyperbolic surface stereo
// Stereo is a half angle at the intersection point of the two
// lines in the tangent plane cross section
static void TwistedTubeBoundingTrap(G4double twistAng, // twist angle
G4double endInnerRad, // inner radius at z = halfZ
G4double endOuterRad, // outer radius at z = halfZ
G4double dPhi, // delta phi
G4TwoVectorList& vertices); // corners of generic trap
// Find XY-coordinates of the corners of the generic trap
// that bounds specified twisted tube
static G4double HyperboloidSurfaceArea(G4double dphi, // delta phi
G4double r0, // radius at z = 0
G4double tanstereo, // tan(stereo)
G4double zmin,
G4double zmax);
// Calculate surface area of the hyperboloid between zmin and zmax
private:
static G4bool CheckSnip(const G4TwoVectorList& contour,
@@ -92,7 +92,7 @@ inline
G4FastSimulationManager* G4LogicalVolume::GetFastSimulationManager () const
{
G4FastSimulationManager* fFSM = nullptr;
if(fRegion != nullptr) fFSM = fRegion->GetFastSimulationManager();
if(fRegion != nullptr) { fFSM = fRegion->GetFastSimulationManager(); }
return fFSM;
}
@@ -105,7 +105,7 @@ G4bool G4LogicalVolume::IsDaughter(const G4VPhysicalVolume* p) const
{
for (const auto & daughter : fDaughters)
{
if (*daughter==*p) return true;
if (*daughter==*p) { return true; }
}
return false;
}
@@ -165,8 +165,9 @@ G4VSensitiveDetector* G4LogicalVolume::GetMasterSensitiveDetector() const
inline
G4UserLimits* G4LogicalVolume::GetUserLimits() const
{
if(fUserLimits != nullptr) return fUserLimits;
if(fRegion != nullptr) return fRegion->GetUserLimits();
if(fUserLimits != nullptr) { return fUserLimits;
}
if(fRegion != nullptr) { return fRegion->GetUserLimits(); }
return nullptr;
}
@@ -268,7 +269,7 @@ inline
G4bool G4LogicalVolume::IsRegion() const
{
G4bool reg = false;
if (fRegion != nullptr) reg = true;
if (fRegion != nullptr) { reg = true; }
return reg;
}
@@ -216,7 +216,7 @@ G4MaterialCutsCouple* G4Region::FindCouple(G4Material* mat)
{
auto c = fMaterialCoupleMap.find(mat);
G4MaterialCutsCouple* couple = nullptr;
if(c!=fMaterialCoupleMap.cend()) couple = (*c).second;
if(c!=fMaterialCoupleMap.cend()) { couple = (*c).second; }
return couple;
}
@@ -70,15 +70,12 @@ G4double G4VoxelLimits::GetMaxExtent(const EAxis pAxis) const
{
return GetMaxXExtent();
}
else if (pAxis==kYAxis)
if (pAxis==kYAxis)
{
return GetMaxYExtent();
}
else
{
assert(pAxis==kZAxis);
return GetMaxZExtent();
}
assert(pAxis==kZAxis);
return GetMaxZExtent();
}
inline
@@ -88,33 +85,30 @@ G4double G4VoxelLimits::GetMinExtent(const EAxis pAxis) const
{
return GetMinXExtent();
}
else if (pAxis==kYAxis)
if (pAxis==kYAxis)
{
return GetMinYExtent();
}
else
{
assert(pAxis==kZAxis);
return GetMinZExtent();
}
assert(pAxis==kZAxis);
return GetMinZExtent();
}
inline
G4bool G4VoxelLimits::IsXLimited() const
{
return !(fxAxisMin==-kInfinity&&fxAxisMax==kInfinity);
return fxAxisMin!=-kInfinity||fxAxisMax!=kInfinity;
}
inline
G4bool G4VoxelLimits::IsYLimited() const
{
return !(fyAxisMin==-kInfinity&&fyAxisMax==kInfinity);
return fyAxisMin!=-kInfinity||fyAxisMax!=kInfinity;
}
inline
G4bool G4VoxelLimits::IsZLimited() const
{
return !(fzAxisMin==-kInfinity&&fzAxisMax==kInfinity);
return fzAxisMin!=-kInfinity||fzAxisMax!=kInfinity;
}
inline
@@ -130,15 +124,12 @@ G4bool G4VoxelLimits::IsLimited(const EAxis pAxis) const
{
return IsXLimited();
}
else if (pAxis==kYAxis)
if (pAxis==kYAxis)
{
return IsYLimited();
}
else
{
assert(pAxis==kZAxis);
return IsZLimited();
}
assert(pAxis==kZAxis);
return IsZLimited();
}
inline
@@ -69,17 +69,17 @@ G4BoundingEnvelope(const std::vector<const G4ThreeVectorList*>& polygons)
G4double xmax = -kInfinity, ymax = -kInfinity, zmax = -kInfinity;
for (const auto & polygon : *fPolygons)
{
for (auto ipoint = polygon->cbegin(); ipoint != polygon->cend(); ++ipoint)
for (const auto & ipoint : *polygon)
{
G4double x = ipoint->x();
if (x < xmin) xmin = x;
if (x > xmax) xmax = x;
G4double y = ipoint->y();
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
G4double z = ipoint->z();
if (z < zmin) zmin = z;
if (z > zmax) zmax = z;
G4double x = ipoint.x();
if (x < xmin) { xmin = x; }
if (x > xmax) { xmax = x; }
G4double y = ipoint.y();
if (y < ymin) { ymin = y; }
if (y > ymax) { ymax = y; }
G4double z = ipoint.z();
if (z < zmin) { zmin = z; }
if (z > zmax) { zmax = z; }
}
}
fMin.set(xmin,ymin,zmin);
@@ -158,9 +158,9 @@ void G4BoundingEnvelope::CheckBoundingPolygons()
for (std::size_t k=0; k<nbases; ++k)
{
std::size_t np = (*fPolygons)[k]->size();
if (np == nsize) continue;
if (np == 1 && k==0) continue;
if (np == 1 && k==nbases-1) continue;
if (np == nsize) { continue; }
if (np == 1 && k==0) { continue; }
if (np == 1 && k==nbases-1) { continue; }
std::ostringstream message;
message << "Badly constructed polygons!"
<< "\nNumber of polygons: " << nbases
@@ -204,12 +204,12 @@ BoundingBoxVsVoxelLimits(const EAxis pAxis,
G4double zmin = fMin.z() + pTransform3D.dz();
G4double zmax = fMax.z() + pTransform3D.dz();
if (xmin-kCarTolerance > xmaxlim) return true;
if (xmax+kCarTolerance < xminlim) return true;
if (ymin-kCarTolerance > ymaxlim) return true;
if (ymax+kCarTolerance < yminlim) return true;
if (zmin-kCarTolerance > zmaxlim) return true;
if (zmax+kCarTolerance < zminlim) return true;
if (xmin-kCarTolerance > xmaxlim) { return true; }
if (xmax+kCarTolerance < xminlim) { return true; }
if (ymin-kCarTolerance > ymaxlim) { return true; }
if (ymax+kCarTolerance < yminlim) { return true; }
if (zmin-kCarTolerance > zmaxlim) { return true; }
if (zmax+kCarTolerance < zminlim) { return true; }
if (xmin >= xminlim && xmax <= xmaxlim &&
ymin >= yminlim && ymax <= ymaxlim &&
@@ -250,12 +250,12 @@ BoundingBoxVsVoxelLimits(const EAxis pAxis,
// Check if the sphere surrounding the bounding box is outside
// the voxel limits
//
if (center.x()-radius > xmaxlim) return true;
if (center.y()-radius > ymaxlim) return true;
if (center.z()-radius > zmaxlim) return true;
if (center.x()+radius < xminlim) return true;
if (center.y()+radius < yminlim) return true;
if (center.z()+radius < zminlim) return true;
if (center.x()-radius > xmaxlim) { return true; }
if (center.y()-radius > ymaxlim) { return true; }
if (center.z()-radius > zmaxlim) { return true; }
if (center.x()+radius < xminlim) { return true; }
if (center.y()+radius < yminlim) { return true; }
if (center.z()+radius < zminlim) { return true; }
return false;
}
@@ -289,12 +289,12 @@ G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
G4double zmin = fMin.z() + pTransform3D.dz();
G4double zmax = fMax.z() + pTransform3D.dz();
if (xmin-kCarTolerance > xmaxlim) return false;
if (xmax+kCarTolerance < xminlim) return false;
if (ymin-kCarTolerance > ymaxlim) return false;
if (ymax+kCarTolerance < yminlim) return false;
if (zmin-kCarTolerance > zmaxlim) return false;
if (zmax+kCarTolerance < zminlim) return false;
if (xmin-kCarTolerance > xmaxlim) { return false; }
if (xmax+kCarTolerance < xminlim) { return false; }
if (ymin-kCarTolerance > ymaxlim) { return false; }
if (ymax+kCarTolerance < yminlim) { return false; }
if (zmin-kCarTolerance > zmaxlim) { return false; }
if (zmax+kCarTolerance < zminlim) { return false; }
if (fPolygons == nullptr)
{
@@ -368,39 +368,39 @@ G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
{
G4double coor;
coor = cx*fMin.x() + cy*fMin.y() + cz*fMin.z() + cd;
if (coor < emin) emin = coor;
if (coor > emax) emax = coor;
if (coor < emin) { emin = coor; }
if (coor > emax) { emax = coor; }
coor = cx*fMax.x() + cy*fMin.y() + cz*fMin.z() + cd;
if (coor < emin) emin = coor;
if (coor > emax) emax = coor;
if (coor < emin) { emin = coor; }
if (coor > emax) { emax = coor; }
coor = cx*fMax.x() + cy*fMax.y() + cz*fMin.z() + cd;
if (coor < emin) emin = coor;
if (coor > emax) emax = coor;
if (coor < emin) { emin = coor; }
if (coor > emax) { emax = coor; }
coor = cx*fMin.x() + cy*fMax.y() + cz*fMin.z() + cd;
if (coor < emin) emin = coor;
if (coor > emax) emax = coor;
if (coor < emin) { emin = coor; }
if (coor > emax) { emax = coor; }
coor = cx*fMin.x() + cy*fMin.y() + cz*fMax.z() + cd;
if (coor < emin) emin = coor;
if (coor > emax) emax = coor;
if (coor < emin) { emin = coor; }
if (coor > emax) { emax = coor; }
coor = cx*fMax.x() + cy*fMin.y() + cz*fMax.z() + cd;
if (coor < emin) emin = coor;
if (coor > emax) emax = coor;
if (coor < emin) { emin = coor; }
if (coor > emax) { emax = coor; }
coor = cx*fMax.x() + cy*fMax.y() + cz*fMax.z() + cd;
if (coor < emin) emin = coor;
if (coor > emax) emax = coor;
if (coor < emin) { emin = coor; }
if (coor > emax) { emax = coor; }
coor = cx*fMin.x() + cy*fMax.y() + cz*fMax.z() + cd;
if (coor < emin) emin = coor;
if (coor > emax) emax = coor;
if (coor < emin) { emin = coor; }
if (coor > emax) { emax = coor; }
}
else
{
for (const auto & polygon : *fPolygons)
{
for (auto ipoint=polygon->cbegin(); ipoint!=polygon->cend(); ++ipoint)
for (const auto & ipoint : *polygon)
{
G4double coor = ipoint->x()*cx + ipoint->y()*cy + ipoint->z()*cz + cd;
if (coor < emin) emin = coor;
if (coor > emax) emax = coor;
G4double coor = ipoint.x()*cx + ipoint.y()*cy + ipoint.z()*cz + cd;
if (coor < emin) { emin = coor; }
if (coor > emax) { emax = coor; }
}
}
}
@@ -412,12 +412,12 @@ G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
// Check if the sphere surrounding the bounding box is outside
// the voxel limits
//
if (center.x()-radius > xmaxlim) return false;
if (center.y()-radius > ymaxlim) return false;
if (center.z()-radius > zmaxlim) return false;
if (center.x()+radius < xminlim) return false;
if (center.y()+radius < yminlim) return false;
if (center.z()+radius < zminlim) return false;
if (center.x()-radius > xmaxlim) { return false; }
if (center.y()-radius > ymaxlim) { return false; }
if (center.z()-radius > zmaxlim) { return false; }
if (center.x()+radius < xminlim) { return false; }
if (center.y()+radius < yminlim) { return false; }
if (center.z()+radius < zminlim) { return false; }
// Transform polygons
//
@@ -452,11 +452,15 @@ G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
{
baseA.resize(bases[k].second);
for (G4int i = 0; i < bases[k].second; ++i)
{
baseA[i] = vertices[bases[k].first + i];
}
baseB.resize(bases[k+1].second);
for (G4int i = 0; i < bases[k+1].second; ++i)
{
baseB[i] = vertices[bases[k+1].first + i];
}
// Find bounding box of current prism
G4Segment3D prismAABB;
@@ -471,52 +475,76 @@ G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
prismAABB.second.z()<= limits.GetMaxZExtent())
{
if (extent.first.x() > prismAABB.first.x())
{
extent.first.setX( prismAABB.first.x() );
}
if (extent.first.y() > prismAABB.first.y())
{
extent.first.setY( prismAABB.first.y() );
}
if (extent.first.z() > prismAABB.first.z())
{
extent.first.setZ( prismAABB.first.z() );
}
if (extent.second.x() < prismAABB.second.x())
{
extent.second.setX(prismAABB.second.x());
}
if (extent.second.y() < prismAABB.second.y())
{
extent.second.setY(prismAABB.second.y());
}
if (extent.second.z() < prismAABB.second.z())
{
extent.second.setZ(prismAABB.second.z());
}
continue;
}
// Check if prismAABB is outside the voxel limits
if (prismAABB.first.x() > limits.GetMaxXExtent()) continue;
if (prismAABB.first.y() > limits.GetMaxYExtent()) continue;
if (prismAABB.first.z() > limits.GetMaxZExtent()) continue;
if (prismAABB.second.x() < limits.GetMinXExtent()) continue;
if (prismAABB.second.y() < limits.GetMinYExtent()) continue;
if (prismAABB.second.z() < limits.GetMinZExtent()) continue;
if (prismAABB.first.x() > limits.GetMaxXExtent()) { continue; }
if (prismAABB.first.y() > limits.GetMaxYExtent()) { continue; }
if (prismAABB.first.z() > limits.GetMaxZExtent()) { continue; }
if (prismAABB.second.x() < limits.GetMinXExtent()) { continue; }
if (prismAABB.second.y() < limits.GetMinYExtent()) { continue; }
if (prismAABB.second.z() < limits.GetMinZExtent()) { continue; }
// Clip edges of the prism by adjusted G4VoxelLimits box
std::vector<G4Segment3D> vecEdges;
CreateListOfEdges(baseA, baseB, vecEdges);
if (ClipEdgesByVoxel(vecEdges, limits, extent)) continue;
if (ClipEdgesByVoxel(vecEdges, limits, extent)) { continue; }
// Some edges of the prism are completely outside of the voxel
// limits, clip selected edges (see bits) of adjusted G4VoxelLimits
// by the prism
G4int bits = 0x000;
if (limits.GetMinXExtent() < prismAABB.first.x())
{
bits |= 0x988; // 1001 1000 1000
}
if (limits.GetMaxXExtent() > prismAABB.second.x())
{
bits |= 0x622; // 0110 0010 0010
}
if (limits.GetMinYExtent() < prismAABB.first.y())
{
bits |= 0x311; // 0011 0001 0001
}
if (limits.GetMaxYExtent() > prismAABB.second.y())
{
bits |= 0xC44; // 1100 0100 0100
}
if (limits.GetMinZExtent() < prismAABB.first.z())
{
bits |= 0x00F; // 0000 0000 1111
}
if (limits.GetMaxZExtent() > prismAABB.second.z())
{
bits |= 0x0F0; // 0000 1111 0000
if (bits == 0xFFF) continue;
}
if (bits == 0xFFF) { continue; }
std::vector<G4Plane3D> vecPlanes;
CreateListOfPlanes(baseA, baseB, vecPlanes);
@@ -530,7 +558,7 @@ G4BoundingEnvelope::CalculateExtent(const EAxis pAxis,
if (pAxis == kYAxis) { emin = extent.first.y(); emax = extent.second.y(); }
if (pAxis == kZAxis) { emin = extent.first.z(); emax = extent.second.z(); }
if (emin > emax) return false;
if (emin > emax) { return false; }
emin -= delta;
emax += delta;
G4double minlim = pVoxelLimits.GetMinExtent(pAxis);
@@ -549,7 +577,7 @@ G4BoundingEnvelope::FindScaleFactor(const G4Transform3D& pTransform3D) const
{
if (pTransform3D.xx() == 1. &&
pTransform3D.yy() == 1. &&
pTransform3D.zz() == 1.) return 1.;
pTransform3D.zz() == 1.) { return 1.; }
G4double xx = pTransform3D.xx();
G4double yx = pTransform3D.yx();
@@ -613,14 +641,22 @@ TransformVertices(const G4Transform3D& pTransform3D,
{
G4ThreeVector offset = pTransform3D.getTranslation();
for (auto i = ia; i != iaend; ++i)
{
for (auto k = (*i)->cbegin(); k != (*i)->cend(); ++k)
{
pVertices.emplace_back((*k) + offset);
}
}
}
else
{
for (auto i = ia; i != iaend; ++i)
{
for (auto k = (*i)->cbegin(); k != (*i)->cend(); ++k)
{
pVertices.push_back(pTransform3D*G4Point3D(*k));
}
}
}
}
@@ -641,14 +677,14 @@ G4BoundingEnvelope::GetPrismAABB(const G4Polygon3D& pBaseA,
for (const auto & it1 : pBaseA)
{
G4double x = it1.x();
if (x < xmin) xmin = x;
if (x > xmax) xmax = x;
if (x < xmin) { xmin = x; }
if (x > xmax) { xmax = x; }
G4double y = it1.y();
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
if (y < ymin) { ymin = y; }
if (y > ymax) { ymax = y; }
G4double z = it1.z();
if (z < zmin) zmin = z;
if (z > zmax) zmax = z;
if (z < zmin) { zmin = z; }
if (z > zmax) { zmax = z; }
}
// Second base
@@ -656,14 +692,14 @@ G4BoundingEnvelope::GetPrismAABB(const G4Polygon3D& pBaseA,
for (const auto & it2 : pBaseB)
{
G4double x = it2.x();
if (x < xmin) xmin = x;
if (x > xmax) xmax = x;
if (x < xmin) { xmin = x; }
if (x > xmax) { xmax = x; }
G4double y = it2.y();
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
if (y < ymin) { ymin = y; }
if (y > ymax) { ymax = y; }
G4double z = it2.z();
if (z < zmin) zmin = z;
if (z > zmax) zmax = z;
if (z < zmin) { zmin = z; }
if (z > zmax) { zmax = z; }
}
// Set bounding box
@@ -735,8 +771,8 @@ G4BoundingEnvelope::CreateListOfPlanes(const G4Polygon3D& baseA,
std::size_t nb = baseB.size();
G4Point3D pa(0.,0.,0.), pb(0.,0.,0.), p0;
G4Normal3D norm;
for (std::size_t i=0; i<na; ++i) pa += baseA[i];
for (std::size_t i=0; i<nb; ++i) pb += baseB[i];
for (std::size_t i=0; i<na; ++i) { pa += baseA[i]; }
for (std::size_t i=0; i<nb; ++i) { pb += baseB[i]; }
pa /= na; pb /= nb; p0 = (pa+pb)/2.;
// Create list of planes
@@ -838,7 +874,7 @@ G4BoundingEnvelope::ClipEdgesByVoxel(const std::vector<G4Segment3D>& pEdges,
G4Point3D p2 = pEdges[k].second;
if (std::abs(p1.x()-p2.x())+
std::abs(p1.y()-p2.y())+
std::abs(p1.z()-p2.z()) < kCarTolerance) continue;
std::abs(p1.z()-p2.z()) < kCarTolerance) { continue; }
G4double d1, d2;
// Clip current edge by X min
d1 = pBox.GetMinXExtent() - p1.x();
+183 -88
View File
@@ -53,7 +53,7 @@ G4double G4GeomTools::TriangleArea(const G4TwoVector& A,
const G4TwoVector& B,
const G4TwoVector& C)
{
G4double Ax = A.x(), Ay = A.y();
G4double Ax = A.x(), Ay = A.y();
return ((B.x()-Ax)*(C.y()-Ay) - (B.y()-Ay)*(C.x()-Ax))*0.5;
}
@@ -76,7 +76,8 @@ G4double G4GeomTools::QuadArea(const G4TwoVector& A,
G4double G4GeomTools::PolygonArea(const G4TwoVectorList& p)
{
auto n = (G4int)p.size();
if (n < 3) return 0.0; // degenerate polygon
if (n < 3) { return 0.0; // degenerate polygon
}
G4double area = p[n-1].x()*p[0].y() - p[0].x()*p[n-1].y();
for(G4int i=1; i<n; ++i)
{
@@ -97,15 +98,15 @@ G4bool G4GeomTools::PointInTriangle(G4double Ax, G4double Ay,
{
if ((Bx-Ax)*(Cy-Ay) - (By-Ay)*(Cx-Ax) > 0.)
{
if ((Ax-Cx)*(Py-Cy) - (Ay-Cy)*(Px-Cx) < 0.) return false;
if ((Bx-Ax)*(Py-Ay) - (By-Ay)*(Px-Ax) < 0.) return false;
if ((Cx-Bx)*(Py-By) - (Cy-By)*(Px-Bx) < 0.) return false;
if ((Ax-Cx)*(Py-Cy) - (Ay-Cy)*(Px-Cx) < 0.) { return false; }
if ((Bx-Ax)*(Py-Ay) - (By-Ay)*(Px-Ax) < 0.) { return false; }
if ((Cx-Bx)*(Py-By) - (Cy-By)*(Px-Bx) < 0.) { return false; }
}
else
{
if ((Ax-Cx)*(Py-Cy) - (Ay-Cy)*(Px-Cx) > 0.) return false;
if ((Bx-Ax)*(Py-Ay) - (By-Ay)*(Px-Ax) > 0.) return false;
if ((Cx-Bx)*(Py-By) - (Cy-By)*(Px-Bx) > 0.) return false;
if ((Ax-Cx)*(Py-Cy) - (Ay-Cy)*(Px-Cx) > 0.) { return false; }
if ((Bx-Ax)*(Py-Ay) - (By-Ay)*(Px-Ax) > 0.) { return false; }
if ((Cx-Bx)*(Py-By) - (Cy-By)*(Px-Bx) > 0.) { return false; }
}
return true;
}
@@ -125,15 +126,15 @@ G4bool G4GeomTools::PointInTriangle(const G4TwoVector& A,
G4double Px = P.x(), Py = P.y();
if ((Bx-Ax)*(Cy-Ay) - (By-Ay)*(Cx-Ax) > 0.)
{
if ((Ax-Cx)*(Py-Cy) - (Ay-Cy)*(Px-Cx) < 0.) return false;
if ((Bx-Ax)*(Py-Ay) - (By-Ay)*(Px-Ax) < 0.) return false;
if ((Cx-Bx)*(Py-By) - (Cy-By)*(Px-Bx) < 0.) return false;
if ((Ax-Cx)*(Py-Cy) - (Ay-Cy)*(Px-Cx) < 0.) { return false; }
if ((Bx-Ax)*(Py-Ay) - (By-Ay)*(Px-Ax) < 0.) { return false; }
if ((Cx-Bx)*(Py-By) - (Cy-By)*(Px-Bx) < 0.) { return false; }
}
else
{
if ((Ax-Cx)*(Py-Cy) - (Ay-Cy)*(Px-Cx) > 0.) return false;
if ((Bx-Ax)*(Py-Ay) - (By-Ay)*(Px-Ax) > 0.) return false;
if ((Cx-Bx)*(Py-By) - (Cy-By)*(Px-Bx) > 0.) return false;
if ((Ax-Cx)*(Py-Cy) - (Ay-Cy)*(Px-Cx) > 0.) { return false; }
if ((Bx-Ax)*(Py-Ay) - (By-Ay)*(Px-Ax) > 0.) { return false; }
if ((Cx-Bx)*(Py-By) - (Cy-By)*(Px-Bx) > 0.) { return false; }
}
return true;
}
@@ -170,7 +171,7 @@ G4bool G4GeomTools::IsConvex(const G4TwoVectorList& polygon)
G4bool gotNegative = false;
G4bool gotPositive = false;
auto n = (G4int)polygon.size();
if (n <= 0) return false;
if (n <= 0) { return false; }
for (G4int icur=0; icur<n; ++icur)
{
G4int iprev = (icur == 0) ? n-1 : icur-1;
@@ -178,10 +179,10 @@ G4bool G4GeomTools::IsConvex(const G4TwoVectorList& polygon)
G4TwoVector e1 = polygon[icur] - polygon[iprev];
G4TwoVector e2 = polygon[inext] - polygon[icur];
G4double cross = e1.x()*e2.y() - e1.y()*e2.x();
if (std::abs(cross) < kCarTolerance) return false;
if (cross < 0) gotNegative = true;
if (cross > 0) gotPositive = true;
if (gotNegative && gotPositive) return false;
if (std::abs(cross) < kCarTolerance) { return false; }
if (cross < 0) { gotNegative = true; }
if (cross > 0) { gotPositive = true; }
if (gotNegative && gotPositive) { return false; }
}
return true;
}
@@ -198,7 +199,7 @@ G4bool G4GeomTools::TriangulatePolygon(const G4TwoVectorList& polygon,
G4bool reply = TriangulatePolygon(polygon,triangles);
auto n = (G4int)triangles.size();
for (G4int i=0; i<n; ++i) result.push_back(polygon[triangles[i]]);
for (G4int i=0; i<n; ++i) { result.push_back(polygon[triangles[i]]); }
return reply;
}
@@ -214,19 +215,20 @@ G4bool G4GeomTools::TriangulatePolygon(const G4TwoVectorList& polygon,
// allocate and initialize list of Vertices in polygon
//
auto n = (G4int)polygon.size();
if (n < 3) return false;
if (n < 3) { return false; }
// we want a counter-clockwise polygon in V
//
//
G4double area = G4GeomTools::PolygonArea(polygon);
auto V = new G4int[n];
if (area > 0.)
for (G4int i=0; i<n; ++i) V[i] = i;
else
for (G4int i=0; i<n; ++i) V[i] = (n-1)-i;
if (area > 0.) {
for (G4int i=0; i<n; ++i) { V[i] = i; }
} else {
for (G4int i=0; i<n; ++i) { V[i] = (n-1)-i; }
}
// Triangulation: remove nv-2 Vertices, creating 1 triangle every time
//
//
G4int nv = n;
G4int count = 2*nv; // error detection counter
for(G4int b=nv-1; nv>2; )
@@ -235,8 +237,8 @@ G4bool G4GeomTools::TriangulatePolygon(const G4TwoVectorList& polygon,
if ((count--) <= 0)
{
delete [] V;
if (area < 0.) std::reverse(result.begin(),result.end());
return false;
if (area < 0.) { std::reverse(result.begin(),result.end()); }
return false;
}
// three consecutive vertices in current polygon, <a,b,c>
@@ -253,13 +255,13 @@ G4bool G4GeomTools::TriangulatePolygon(const G4TwoVectorList& polygon,
// remove vertex b from remaining polygon
nv--;
for(G4int i=b; i<nv; ++i) V[i] = V[i+1];
for(G4int i=b; i<nv; ++i) { V[i] = V[i+1]; }
count = 2*nv; // resest error detection counter
}
}
delete [] V;
if (area < 0.) std::reverse(result.begin(),result.end());
if (area < 0.) { std::reverse(result.begin(),result.end()); }
return true;
}
@@ -279,8 +281,8 @@ G4bool G4GeomTools::CheckSnip(const G4TwoVectorList& contour,
G4double Ax = contour[V[a]].x(), Ay = contour[V[a]].y();
G4double Bx = contour[V[b]].x(), By = contour[V[b]].y();
G4double Cx = contour[V[c]].x(), Cy = contour[V[c]].y();
if ((Bx-Ax)*(Cy-Ay) - (By-Ay)*(Cx-Ax) < kCarTolerance) return false;
if ((Bx-Ax)*(Cy-Ay) - (By-Ay)*(Cx-Ax) < kCarTolerance) { return false; }
// check that there is no point inside Triangle
G4double xmin = std::min(std::min(Ax,Bx),Cx);
G4double xmax = std::max(std::max(Ax,Bx),Cx);
@@ -288,12 +290,12 @@ G4bool G4GeomTools::CheckSnip(const G4TwoVectorList& contour,
G4double ymax = std::max(std::max(Ay,By),Cy);
for (G4int i=0; i<n; ++i)
{
if((i == a) || (i == b) || (i == c)) continue;
if((i == a) || (i == b) || (i == c)) { continue; }
G4double Px = contour[V[i]].x();
if (Px < xmin || Px > xmax) continue;
if (Px < xmin || Px > xmax) { continue; }
G4double Py = contour[V[i]].y();
if (Py < ymin || Py > ymax) continue;
if (PointInTriangle(Ax,Ay,Bx,By,Cx,Cy,Px,Py)) return false;
if (Py < ymin || Py > ymax) { continue; }
if (PointInTriangle(Ax,Ay,Bx,By,Cx,Cy,Px,Py)) { return false; }
}
return true;
}
@@ -304,7 +306,7 @@ G4bool G4GeomTools::CheckSnip(const G4TwoVectorList& contour,
void G4GeomTools::RemoveRedundantVertices(G4TwoVectorList& polygon,
std::vector<G4int>& iout,
G4double tolerance)
G4double tolerance)
{
iout.resize(0);
// set tolerance squared
@@ -317,7 +319,7 @@ void G4GeomTools::RemoveRedundantVertices(G4TwoVectorList& polygon,
// Main loop: check every three consecutive points, if the points
// are collinear then mark middle point for removal
//
G4int icur = 0, iprev = 0, inext = 0, nout = 0;
G4int icur = 0, iprev = 0, inext = 0, nout = 0;
for (G4int i=0; i<nv; ++i)
{
icur = i; // index of current point
@@ -325,18 +327,18 @@ void G4GeomTools::RemoveRedundantVertices(G4TwoVectorList& polygon,
for (G4int k=1; k<nv+1; ++k) // set index of previous point
{
iprev = icur - k;
if (iprev < 0) iprev += nv;
if (polygon[iprev].x() != removeIt) break;
if (iprev < 0) { iprev += nv; }
if (polygon[iprev].x() != removeIt) { break; }
}
for (G4int k=1; k<nv+1; ++k) // set index of next point
{
inext = icur + k;
if (inext >= nv) inext -= nv;
if (polygon[inext].x() != removeIt) break;
if (inext >= nv) { inext -= nv; }
if (polygon[inext].x() != removeIt) { break; }
}
if (iprev == inext) break; // degenerate polygon, stop
if (iprev == inext) { break; } // degenerate polygon, stop
// Calculate parameters of triangle (iprev->icur->inext),
// if triangle is too small or too narrow then mark current
@@ -344,7 +346,7 @@ void G4GeomTools::RemoveRedundantVertices(G4TwoVectorList& polygon,
G4TwoVector e1 = polygon[iprev] - polygon[icur];
G4TwoVector e2 = polygon[inext] - polygon[icur];
// Check length of edges, then check height of the triangle
// Check length of edges, then check height of the triangle
G4double leng1 = e1.mag2();
G4double leng2 = e2.mag2();
G4double leng3 = (e2-e1).mag2();
@@ -368,18 +370,18 @@ void G4GeomTools::RemoveRedundantVertices(G4TwoVectorList& polygon,
icur = 0;
if (nv - nout < 3) // degenerate polygon, remove all points
{
for (G4int i=0; i<nv; ++i) iout.push_back(i);
for (G4int i=0; i<nv; ++i) { iout.push_back(i); }
polygon.resize(0);
nv = 0;
}
for (G4int i=0; i<nv; ++i) // move points, if required
{
if (polygon[i].x() != removeIt)
if (polygon[i].x() != removeIt) {
polygon[icur++] = polygon[i];
else
iout.push_back(i);
} else {
iout.push_back(i); }
}
if (icur < nv) polygon.resize(icur);
if (icur < nv) { polygon.resize(icur); }
return;
}
@@ -398,15 +400,15 @@ G4bool G4GeomTools::DiskExtent(G4double rmin, G4double rmax,
//
pmin.set(0,0);
pmax.set(0,0);
if (rmin < 0) return false;
if (rmax <= rmin + kCarTolerance) return false;
if (delPhi <= 0 + kCarTolerance) return false;
if (rmin < 0) { return false; }
if (rmax <= rmin + kCarTolerance) { return false; }
if (delPhi <= 0 + kCarTolerance) { return false; }
// calculate extent
//
pmin.set(-rmax,-rmax);
pmax.set( rmax, rmax);
if (delPhi >= CLHEP::twopi) return true;
if (delPhi >= CLHEP::twopi) { return true; }
DiskExtent(rmin,rmax,
std::sin(startPhi),std::cos(startPhi),
@@ -433,25 +435,25 @@ void G4GeomTools::DiskExtent(G4double rmin, G4double rmax,
pmin.set(-rmax,-rmax);
pmax.set( rmax, rmax);
if (std::abs(sinEnd-sinStart) < kCarTolerance &&
std::abs(cosEnd-cosStart) < kCarTolerance) return;
if (std::abs(sinEnd-sinStart) < kCarTolerance &&
std::abs(cosEnd-cosStart) < kCarTolerance) { return; }
// get start and end quadrants
//
// 1 | 0
// ---+---
// ---+---
// 3 | 2
//
G4int icase = (cosEnd < 0) ? 1 : 0;
if (sinEnd < 0) icase += 2;
if (cosStart < 0) icase += 4;
if (sinStart < 0) icase += 8;
if (sinEnd < 0) { icase += 2; }
if (cosStart < 0) { icase += 4; }
if (sinStart < 0) { icase += 8; }
switch (icase)
{
// start quadrant 0
case 0: // start->end : 0->0
if (sinEnd < sinStart) break;
if (sinEnd < sinStart) { break; }
pmin.set(rmin*cosEnd,rmin*sinStart);
pmax.set(rmax*cosStart,rmax*sinEnd );
break;
@@ -473,7 +475,7 @@ void G4GeomTools::DiskExtent(G4double rmin, G4double rmax,
pmax.set(rmax,std::max(rmax*sinStart,rmax*sinEnd));
break;
case 5: // start->end : 1->1
if (sinEnd > sinStart) break;
if (sinEnd > sinStart) { break; }
pmin.set(rmax*cosEnd,rmin*sinEnd );
pmax.set(rmin*cosStart,rmax*sinStart);
break;
@@ -495,7 +497,7 @@ void G4GeomTools::DiskExtent(G4double rmin, G4double rmax,
pmax.set(rmax,rmax);
break;
case 10: // start->end : 2->2
if (sinEnd < sinStart) break;
if (sinEnd < sinStart) { break; }
pmin.set(rmin*cosStart,rmax*sinStart);
pmax.set(rmax*cosEnd,rmin*sinEnd );
break;
@@ -517,7 +519,7 @@ void G4GeomTools::DiskExtent(G4double rmin, G4double rmax,
pmax.set(rmax*cosEnd,std::max(rmin*sinStart,rmin*sinEnd));
break;
case 15: // start->end : 3->3
if (sinEnd > sinStart) break;
if (sinEnd > sinStart) { break; }
pmin.set(rmax*cosStart,rmax*sinEnd);
pmax.set(rmin*cosEnd,rmin*sinStart);
break;
@@ -573,8 +575,8 @@ G4double G4GeomTools::comp_ellint_2(G4double e)
G4double a = 1.;
G4double b = std::sqrt((1. - e)*(1. + e));
if (b == 1.) return CLHEP::halfpi;
if (b == 0.) return 1.;
if (b == 1.) { return CLHEP::halfpi; }
if (b == 0.) { return 1.; }
G4double x = 1.;
G4double y = b;
@@ -621,7 +623,7 @@ G4ThreeVector G4GeomTools::QuadAreaNormal(const G4ThreeVector& A,
G4ThreeVector G4GeomTools::PolygonAreaNormal(const G4ThreeVectorList& p)
{
auto n = (G4int)p.size();
if (n < 3) return {0,0,0}; // degerate polygon
if (n < 3) { return {0,0,0}; } // degerate polygon
G4ThreeVector normal = p[n-1].cross(p[0]);
for(G4int i=1; i<n; ++i)
{
@@ -642,10 +644,10 @@ G4double G4GeomTools::DistancePointSegment(const G4ThreeVector& P,
G4ThreeVector AB = B - A;
G4double u = AP.dot(AB);
if (u <= 0) return AP.mag(); // closest point is A
if (u <= 0) { return AP.mag(); } // closest point is A
G4double len2 = AB.mag2();
if (u >= len2) return (B-P).mag(); // closest point is B
if (u >= len2) { return (B-P).mag(); } // closest point is B
return ((u/len2)*AB - AP).mag(); // distance to line
}
@@ -663,10 +665,10 @@ G4GeomTools::ClosestPointOnSegment(const G4ThreeVector& P,
G4ThreeVector AB = B - A;
G4double u = AP.dot(AB);
if (u <= 0) return A; // closest point is A
if (u <= 0) { return A; } // closest point is A
G4double len2 = AB.mag2();
if (u >= len2) return B; // closest point is B
if (u >= len2) { return B; } // closest point is B
G4double t = u/len2;
return A + t*AB; // closest point on segment
@@ -679,7 +681,7 @@ G4GeomTools::ClosestPointOnSegment(const G4ThreeVector& P,
// The implementation is based on the algorithm published in
// "Geometric Tools for Computer Graphics", Philip J Scheider and
// David H Eberly, Elsevier Science (USA), 2003.
//
//
// The algorithm is also available at:
// http://www.geometrictools.com/Documentation/DistancePoint3Triangle3.pdf
@@ -722,10 +724,11 @@ G4GeomTools::ClosestPointOnTriangle(const G4ThreeVector& P,
*/
G4int region = -1;
if (t0+t1 <= det)
if (t0+t1 <= det) {
region = (t0 < 0) ? ((t1 < 0) ? 4 : 3) : ((t1 < 0) ? 5 : 0);
else
} else {
region = (t0 < 0) ? 2 : ((t1 < 0) ? 6 : 1);
}
switch (region)
{
@@ -736,8 +739,8 @@ G4GeomTools::ClosestPointOnTriangle(const G4ThreeVector& P,
}
case 1: // edge BC
{
G4double numer = c + e - b - d;
if (numer <= 0) return C;
G4double numer = c + e - b - d;
if (numer <= 0) { return C; }
G4double denom = a - 2*b + c;
return (numer >= denom) ? B : C + (numer/denom)*(edge0-edge1);
}
@@ -758,7 +761,7 @@ G4GeomTools::ClosestPointOnTriangle(const G4ThreeVector& P,
return (e >= 0) ? A : ((-e >= c) ? C : A + (-e/c)*edge1);
case 4: // edge AB or AC
if (d < 0) return (-d >= a) ? B : A + (-d/a)*edge0;
if (d < 0) { return (-d >= a) ? B : A + (-d/a)*edge0; }
return (e >= 0) ? A : ((-e >= c) ? C : A + (-e/c)*edge1);
case 5: // edge AB
@@ -777,7 +780,7 @@ G4GeomTools::ClosestPointOnTriangle(const G4ThreeVector& P,
// same: (d >= 0) ? A : ((-d >= a) ? B : A + (-d/a)*edge0)
return (tmp1 <= 0) ? B : (( d >= 0) ? A : A + (-d/a)*edge0);
}
default: // impossible case
default: // impossible case
return {kInfinity,kInfinity,kInfinity};
}
}
@@ -799,22 +802,22 @@ G4GeomTools::SphereExtent(G4double rmin, G4double rmax,
//
pmin.set(0,0,0);
pmax.set(0,0,0);
if (rmin < 0) return false;
if (rmax <= rmin + kCarTolerance) return false;
if (delTheta <= 0 + kCarTolerance) return false;
if (delPhi <= 0 + kCarTolerance) return false;
if (rmin < 0) { return false; }
if (rmax <= rmin + kCarTolerance) { return false; }
if (delTheta <= 0 + kCarTolerance) { return false; }
if (delPhi <= 0 + kCarTolerance) { return false; }
G4double stheta = startTheta;
G4double dtheta = delTheta;
if (stheta < 0 && stheta > CLHEP::pi) return false;
if (stheta + dtheta > CLHEP::pi) dtheta = CLHEP::pi - stheta;
if (dtheta <= 0 + kCarTolerance) return false;
if (stheta < 0 && stheta > CLHEP::pi) { return false; }
if (stheta + dtheta > CLHEP::pi) { dtheta = CLHEP::pi - stheta; }
if (dtheta <= 0 + kCarTolerance) { return false; }
// calculate extent
//
pmin.set(-rmax,-rmax,-rmax);
pmax.set( rmax, rmax, rmax);
if (dtheta >= CLHEP::pi && delPhi >= CLHEP::twopi) return true;
if (dtheta >= CLHEP::pi && delPhi >= CLHEP::twopi) { return true; }
G4double etheta = stheta + dtheta;
G4double sinStart = std::sin(stheta);
@@ -824,8 +827,8 @@ G4GeomTools::SphereExtent(G4double rmin, G4double rmax,
G4double rhomin = rmin*std::min(sinStart,sinEnd);
G4double rhomax = rmax;
if (stheta > CLHEP::halfpi) rhomax = rmax*sinStart;
if (etheta < CLHEP::halfpi) rhomax = rmax*sinEnd;
if (stheta > CLHEP::halfpi) { rhomax = rmax*sinStart; }
if (etheta < CLHEP::halfpi) { rhomax = rmax*sinEnd; }
G4TwoVector xymin,xymax;
DiskExtent(rhomin,rhomax,
@@ -839,3 +842,95 @@ G4GeomTools::SphereExtent(G4double rmin, G4double rmax,
pmax.set(xymax.x(),xymax.y(),zmax);
return true;
}
///////////////////////////////////////////////////////////////////////
//
// Calculate hyperbolic surface stereo
G4double
G4GeomTools::HypeStereo(G4double r0, G4double r, G4double h)
{
static const G4double kCarTolerance =
G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
if (std::abs(r - r0) < kCarTolerance) { return 0.; }
return std::atan(std::sqrt((r - r0)*(r + r0))/std::abs(h));
}
///////////////////////////////////////////////////////////////////////
//
// Find XY-coordinates of the corners of the bounding generic trap
// for the specified twisted tube
void
G4GeomTools::TwistedTubeBoundingTrap(G4double twistAng,
G4double endInnerRad,
G4double endOuterRad,
G4double dPhi,
G4TwoVectorList& vertices)
{
vertices.resize(8);
G4double rmin = std::abs(endInnerRad);
G4double rmax = std::abs(endOuterRad);
// Set untwisted vertices
G4double phi = dPhi/2.;
G4double sinphi = std::sin(phi);
G4double cosphi = std::cos(phi);
G4double tanphi = std::tan(phi);
vertices[0].set(rmin*cosphi, rmin*sinphi);
vertices[1].set(rmax, rmax*tanphi);
vertices[2].set(rmax,-rmax*tanphi);
vertices[3].set(rmin*cosphi,-rmin*sinphi);
vertices[4] = vertices[0];
vertices[5] = vertices[1];
vertices[6] = vertices[2];
vertices[7] = vertices[3];
// Twist vertices
G4double ang = twistAng/2.;
for(auto i = 0; i < 4; ++i)
{
vertices[i].rotate(-ang); // vertices at -halfz
vertices[i + 4].rotate(ang); // vertices at +halfz
}
}
///////////////////////////////////////////////////////////////////////
//
// Calculate surface area of hyperboloid between zmin and zmax
G4double
G4GeomTools::HyperboloidSurfaceArea(G4double dphi, G4double r0, G4double tanstereo,
G4double zmin, G4double zmax)
{
static const G4double kCarTolerance =
G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
G4double a = std::abs(r0); // radius at z = 0
G4double t = std::abs(tanstereo); // tan(stereo)
G4double phi = std::abs(dphi); // delta phi
// Check spesial cases: cylindrical and conical surfaces
if (t < kCarTolerance) { return a*std::abs(zmax - zmin)*phi; } // cylinder
G4double rmin = std::hypot(t*zmin, a); // radius at zmin
G4double rmax = std::hypot(t*zmax, a); // radius at zmax
if (a < kCarTolerance) // cone
{
G4double smin = rmin*std::hypot(rmin, zmin);
G4double smax = rmax*std::hypot(rmax, zmax);
return (zmin*zmax < 0.) ? (smin + smax)*phi/2. : std::abs(smax - smin)*phi/2.;
}
// Find surface area
G4double tt = t*t;
G4double aa = a*a;
G4double cc = aa/tt;
G4double k = std::sqrt(aa + cc)/cc;
G4double hmin = std::abs(zmin);
G4double smin = a*(hmin*std::hypot(1., k*hmin) + std::asinh(k*hmin)/k);
if (zmax == -zmin) { return smin*phi; }
G4double hmax = std::abs(zmax);
G4double smax = a*(hmax*std::hypot(1., k*hmax) + std::asinh(k*hmax)/k);
return (zmin*zmax < 0.) ? (smin + smax)*phi/2. :std::abs(smax - smin)*phi/2.;
}
@@ -78,7 +78,7 @@ namespace // Data structures / mutexes for parallel optimisation
G4ThreadLocal G4GeometryManager* G4GeometryManager::fgInstance = nullptr;
// Static *global* class data
G4bool G4GeometryManager::fParallelVoxelOptimisationRequested = false;
G4bool G4GeometryManager::fParallelVoxelOptimisationRequested = true;
// Records User choice to use parallel voxel optimisation (or not)
G4bool G4GeometryManager::fOptimiseInParallelConfigured = false;
@@ -102,14 +102,14 @@ void G4LogicalCrystalVolume::SetMillerOrientation(G4int h,
G4ThreeVector norm = (h*GetBasis(0)+k*GetBasis(1)+l*GetBasis(2)).unit();
if (verboseLevel>1) G4cout << " norm = " << norm << G4endl;
if (verboseLevel>1) { G4cout << " norm = " << norm << G4endl; }
// Aligns geometry +Z axis with lattice (hkl) normal
fOrient = G4RotationMatrix::IDENTITY;
fOrient.rotateZ(rot).rotateY(norm.theta()).rotateZ(norm.phi());
fInverse = fOrient.inverse();
if (verboseLevel>1) G4cout << " fOrient = " << fOrient << G4endl;
if (verboseLevel>1) { G4cout << " fOrient = " << fOrient << G4endl; }
// FIXME: Is this equivalent to (phi,theta,rot) Euler angles???
}
@@ -512,10 +512,11 @@ G4LogicalVolume::IsAncestor(const G4VPhysicalVolume* aVolume) const
G4bool isDaughter = IsDaughter(aVolume);
if (!isDaughter)
{
for (auto itDau = fDaughters.cbegin(); itDau != fDaughters.cend(); ++itDau)
for (const auto & daughter : fDaughters)
{
isDaughter = (*itDau)->GetLogicalVolume()->IsAncestor(aVolume);
if (isDaughter) break;
isDaughter = daughter->GetLogicalVolume()->IsAncestor(aVolume);
if (isDaughter) { break;
}
}
}
return isDaughter;
@@ -531,9 +532,8 @@ G4LogicalVolume::IsAncestor(const G4VPhysicalVolume* aVolume) const
G4int G4LogicalVolume::TotalVolumeEntities() const
{
G4int vols = 1;
for (auto itDau = fDaughters.cbegin(); itDau != fDaughters.cend(); ++itDau)
for (auto physDaughter : fDaughters)
{
G4VPhysicalVolume* physDaughter = (*itDau);
vols += physDaughter->GetMultiplicity()
*physDaughter->GetLogicalVolume()->TotalVolumeEntities();
}
@@ -599,9 +599,8 @@ G4double G4LogicalVolume::GetMass(G4bool forced,
// and if required by the propagate flag, add the real daughter's
// one computed recursively
for (auto itDau = fDaughters.cbegin(); itDau != fDaughters.cend(); ++itDau)
for (const auto & physDaughter : fDaughters)
{
G4VPhysicalVolume* physDaughter = (*itDau);
G4LogicalVolume* logDaughter = physDaughter->GetLogicalVolume();
G4double subMass = 0.0;
G4VSolid* daughterSolid = nullptr;
@@ -679,7 +678,8 @@ G4bool G4LogicalVolume::ChangeDaughtersType(EVolume aType)
//
void G4LogicalVolume::SetVisAttributes (const G4VisAttributes& VA)
{
if (G4Threading::IsWorkerThread()) return;
if (G4Threading::IsWorkerThread()) { return;
}
fVisAttributes = std::make_shared<const G4VisAttributes>(VA);
}
@@ -689,6 +689,7 @@ void G4LogicalVolume::SetVisAttributes (const G4VisAttributes& VA)
//
void G4LogicalVolume::SetVisAttributes (const G4VisAttributes* pVA)
{
if (G4Threading::IsWorkerThread()) return;
if (G4Threading::IsWorkerThread()) { return;
}
fVisAttributes = std::shared_ptr<const G4VisAttributes>(pVA,[](const G4VisAttributes*){});
}
@@ -90,10 +90,10 @@ void G4LogicalVolumeStore::Clean()
G4LogicalVolumeStore* store = GetInstance();
for(auto pos=store->cbegin(); pos!=store->cend(); ++pos)
for(const auto & pos : *store)
{
if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
if (*pos != nullptr) { (*pos)->Lock(); delete *pos; }
if (pos != nullptr) { pos->Lock(); delete pos; }
}
store->bmap.clear(); store->mvalid = false;
@@ -118,19 +118,19 @@ void G4LogicalVolumeStore::SetNotifier(G4VStoreNotifier* pNotifier)
void G4LogicalVolumeStore::UpdateMap()
{
G4AutoLock l(&mapMutex); // to avoid thread contention at initialisation
if (mvalid) return;
if (mvalid) { return; }
bmap.clear();
for(auto pos=GetInstance()->cbegin(); pos!=GetInstance()->cend(); ++pos)
for(const auto & pos : *GetInstance())
{
const G4String& vol_name = (*pos)->GetName();
const G4String& vol_name = pos->GetName();
auto it = bmap.find(vol_name);
if (it != bmap.cend())
{
it->second.push_back(*pos);
it->second.push_back(pos);
}
else
{
std::vector<G4LogicalVolume*> vol_vec { *pos };
std::vector<G4LogicalVolume*> vol_vec { pos };
bmap.insert(std::make_pair(vol_name, vol_vec));
}
}
@@ -228,10 +228,7 @@ G4LogicalVolumeStore::GetVolume(const G4String& name, G4bool verbose,
{
return pos->second[pos->second.size()-1];
}
else
{
return pos->second[0];
}
return pos->second[0];
}
if (verbose)
{
@@ -92,10 +92,10 @@ void G4PhysicalVolumeStore::Clean()
G4PhysicalVolumeStore* store = GetInstance();
for(auto pos=store->cbegin(); pos!=store->cend(); ++pos)
for(const auto & pos : *store)
{
if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
delete *pos;
delete pos;
}
store->bmap.clear(); store->mvalid = false;
@@ -120,19 +120,19 @@ void G4PhysicalVolumeStore::SetNotifier(G4VStoreNotifier* pNotifier)
void G4PhysicalVolumeStore::UpdateMap()
{
G4AutoLock l(&mapMutex); // to avoid thread contention at initialisation
if (mvalid) return;
if (mvalid) { return; }
bmap.clear();
for(auto pos=GetInstance()->cbegin(); pos!=GetInstance()->cend(); ++pos)
for(const auto & pos : *GetInstance())
{
const G4String& vol_name = (*pos)->GetName();
const G4String& vol_name = pos->GetName();
auto it = bmap.find(vol_name);
if (it != bmap.cend())
{
it->second.push_back(*pos);
it->second.push_back(pos);
}
else
{
std::vector<G4VPhysicalVolume*> vol_vec { *pos };
std::vector<G4VPhysicalVolume*> vol_vec { pos };
bmap.insert(std::make_pair(vol_name, vol_vec));
}
}
@@ -233,10 +233,7 @@ G4PhysicalVolumeStore::GetVolume(const G4String& name, G4bool verbose,
{
return pos->second[pos->second.size()-1];
}
else
{
return pos->second[0];
}
return pos->second[0];
}
if (verbose)
{
@@ -454,16 +454,13 @@ G4ReflectedSolid::CreatePolyhedron () const
polyhedron->Transform(*fDirectTransform3D);
return polyhedron;
}
else
{
std::ostringstream message;
message << "Solid - " << GetName()
<< " - original solid has no" << G4endl
<< "corresponding polyhedron. Returning NULL!";
G4Exception("G4ReflectedSolid::CreatePolyhedron()",
"GeomMgt1001", JustWarning, message);
return nullptr;
}
std::ostringstream message;
message << "Solid - " << GetName()
<< " - original solid has no" << G4endl
<< "corresponding polyhedron. Returning NULL!";
G4Exception("G4ReflectedSolid::CreatePolyhedron()",
"GeomMgt1001", JustWarning, message);
return nullptr;
}
/////////////////////////////////////////////////////////
+13 -10
View File
@@ -65,7 +65,6 @@ const G4RegionManager& G4Region::GetSubInstanceManager()
G4Region::G4Region(const G4String& pName)
: fName(pName)
{
instanceID = subInstanceManager.CreateSubInstance();
G4MT_fsmanager = nullptr;
G4MT_rsaction = nullptr;
@@ -205,7 +204,7 @@ void G4Region::ScanVolumeTree(G4LogicalVolume* lv, G4bool region)
// Stop recursion here if no further daughters are involved
//
if(noDaughters==0) return;
if(noDaughters==0) { return; }
G4VPhysicalVolume* daughterPVol = lv->GetDaughter(0);
if (daughterPVol->IsParameterised())
@@ -397,9 +396,9 @@ void G4Region::UpdateMaterialList()
// Loop over the root logical volumes and rebuild the list
// of materials from scratch
//
for (auto pLV=fRootVolumes.cbegin(); pLV!=fRootVolumes.cend(); ++pLV)
for (const auto & rootVolume : fRootVolumes)
{
ScanVolumeTree(*pLV, true);
ScanVolumeTree(rootVolume, true);
}
}
@@ -412,9 +411,13 @@ void G4Region::UpdateMaterialList()
void G4Region::SetWorld(G4VPhysicalVolume* wp)
{
if(wp == nullptr)
{ fWorldPhys = nullptr; }
{
fWorldPhys = nullptr;
}
else
{ if(BelongsTo(wp)) fWorldPhys = wp; }
{
if(BelongsTo(wp)) { fWorldPhys = wp; }
}
return;
}
@@ -487,16 +490,16 @@ G4Region* G4Region::GetParentRegion(G4bool& unique) const
// Loop over all logical volumes in the store
//
for(auto lvItr=lvStore->cbegin(); lvItr!=lvStore->cend(); ++lvItr)
for(const auto & lvol : *lvStore)
{
std::size_t nD = (*lvItr)->GetNoDaughters();
G4Region* aR = (*lvItr)->GetRegion();
std::size_t nD = lvol->GetNoDaughters();
G4Region* aR = lvol->GetRegion();
// Loop over all daughters of each logical volume
//
for(std::size_t iD=0; iD<nD; ++iD)
{
if((*lvItr)->GetDaughter(iD)->GetLogicalVolume()->GetRegion()==this)
if(lvol->GetDaughter(iD)->GetLogicalVolume()->GetRegion()==this)
{
if(parent != nullptr)
{
+18 -18
View File
@@ -93,10 +93,10 @@ void G4RegionStore::Clean()
G4RegionStore* store = GetInstance();
for(auto pos=store->cbegin(); pos!=store->cend(); ++pos)
for(const auto & pos : *store)
{
if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
delete *pos;
delete pos;
}
store->bmap.clear(); store->mvalid = false;
@@ -121,19 +121,19 @@ void G4RegionStore::SetNotifier(G4VStoreNotifier* pNotifier)
void G4RegionStore::UpdateMap()
{
G4AutoLock l(&mapMutex); // to avoid thread contention at initialisation
if (mvalid) return;
if (mvalid) { return; }
bmap.clear();
for(auto pos=GetInstance()->cbegin(); pos!=GetInstance()->cend(); ++pos)
for(const auto & pos : *GetInstance())
{
const G4String& reg_name = (*pos)->GetName();
const G4String& reg_name = pos->GetName();
auto it = bmap.find(reg_name);
if (it != bmap.cend())
{
it->second.push_back(*pos);
it->second.push_back(pos);
}
else
{
std::vector<G4Region*> reg_vec { *pos };
std::vector<G4Region*> reg_vec { pos };
bmap.insert(std::make_pair(reg_name, reg_vec));
}
}
@@ -226,9 +226,9 @@ G4RegionStore* G4RegionStore::GetInstance()
//
G4bool G4RegionStore::IsModified() const
{
for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i)
for (const auto & i : *GetInstance())
{
if ((*i)->IsModified()) { return true; }
if (i->IsModified()) { return true; }
}
return false;
}
@@ -240,9 +240,9 @@ G4bool G4RegionStore::IsModified() const
//
void G4RegionStore::ResetRegionModified()
{
for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i)
for (const auto & i : *GetInstance())
{
(*i)->RegionModified(false);
i->RegionModified(false);
}
}
@@ -252,11 +252,11 @@ void G4RegionStore::ResetRegionModified()
//
void G4RegionStore::UpdateMaterialList(G4VPhysicalVolume* currentWorld)
{
for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i)
for (const auto & i : *GetInstance())
{
if((*i)->IsInMassGeometry() || (*i)->IsInParallelGeometry()
if(i->IsInMassGeometry() || i->IsInParallelGeometry()
|| (currentWorld != nullptr))
{ (*i)->UpdateMaterialList(); }
{ i->UpdateMaterialList(); }
}
}
@@ -319,8 +319,8 @@ void G4RegionStore::SetWorldVolume()
{
// Reset all pointers first
//
for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i)
{ (*i)->SetWorld(nullptr); }
for (const auto & i : *GetInstance())
{ i->SetWorld(nullptr); }
// Find world volumes
//
@@ -334,8 +334,8 @@ void G4RegionStore::SetWorldVolume()
// Now 'fPhys' is a world volume, set it to regions that belong to it.
//
for (auto i=GetInstance()->cbegin(); i!=GetInstance()->cend(); ++i)
{ (*i)->SetWorld(fPhys); }
for (const auto & i : *GetInstance())
{ i->SetWorld(fPhys); }
}
}
@@ -195,14 +195,11 @@ G4bool G4SmartVoxelHeader::operator == (const G4SmartVoxelHeader& pHead) const
{
return false;
}
else
leftHeader = leftProxy->GetHeader();
rightHeader = rightProxy->GetHeader();
if (!(*leftHeader == *rightHeader))
{
leftHeader = leftProxy->GetHeader();
rightHeader = rightProxy->GetHeader();
if (!(*leftHeader == *rightHeader))
{
return false;
}
return false;
}
}
else
@@ -211,23 +208,18 @@ G4bool G4SmartVoxelHeader::operator == (const G4SmartVoxelHeader& pHead) const
{
return false;
}
else
leftNode = leftProxy->GetNode();
rightNode = rightProxy->GetNode();
if (!(*leftNode == *rightNode))
{
leftNode = leftProxy->GetNode();
rightNode = rightProxy->GetNode();
if (!(*leftNode == *rightNode))
{
return false;
}
return false;
}
}
}
return true;
}
else
{
return false;
}
return false;
}
// ***************************************************************************
@@ -127,7 +127,7 @@ void G4SmartVoxelStat::CountHeadsAndNodes( const G4SmartVoxelHeader* head )
for(std::size_t i=0; i<numSlices; ++i)
{
const G4SmartVoxelProxy *proxy = head->GetSlice(i);
if (proxy == lastProxy) continue;
if (proxy == lastProxy) { continue; }
lastProxy = proxy;
+8 -11
View File
@@ -89,10 +89,10 @@ void G4SolidStore::Clean()
G4SolidStore* store = GetInstance();
for(auto pos=store->cbegin(); pos!=store->cend(); ++pos)
for(const auto & pos : *store)
{
if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
delete *pos;
delete pos;
}
store->bmap.clear(); store->mvalid = false;
@@ -117,19 +117,19 @@ void G4SolidStore::SetNotifier(G4VStoreNotifier* pNotifier)
void G4SolidStore::UpdateMap()
{
G4AutoLock l(&mapMutex); // to avoid thread contention at initialisation
if (mvalid) return;
if (mvalid) { return; }
bmap.clear();
for(auto pos=GetInstance()->cbegin(); pos!=GetInstance()->cend(); ++pos)
for(const auto & pos : *GetInstance())
{
const G4String& sol_name = (*pos)->GetName();
const G4String& sol_name = pos->GetName();
auto it = bmap.find(sol_name);
if (it != bmap.cend())
{
it->second.push_back(*pos);
it->second.push_back(pos);
}
else
{
std::vector<G4VSolid*> sol_vec { *pos };
std::vector<G4VSolid*> sol_vec { pos };
bmap.insert(std::make_pair(sol_name, sol_vec));
}
}
@@ -227,10 +227,7 @@ G4VSolid* G4SolidStore::GetSolid(const G4String& name, G4bool verbose,
{
return pos->second[pos->second.size()-1];
}
else
{
return pos->second[0];
}
return pos->second[0];
}
if (verbose)
{
@@ -65,12 +65,8 @@ G4TouchableHistory::GetTranslation(G4int depth) const
{
return ftlate;
}
else
{
*ctrans =
fhistory.GetTransform(CalculateHistoryIndex(depth)).NetTranslation();
return *ctrans;
}
*ctrans = fhistory.GetTransform(CalculateHistoryIndex(depth)).NetTranslation();
return *ctrans;
}
const G4RotationMatrix*
@@ -86,9 +82,6 @@ G4TouchableHistory::GetRotation(G4int depth) const
{
return &frot;
}
else
{
*rotM = fhistory.GetTransform(CalculateHistoryIndex(depth)).NetRotation();
return rotM;
}
*rotM = fhistory.GetTransform(CalculateHistoryIndex(depth)).NetRotation();
return rotM;
}
+3 -4
View File
@@ -224,22 +224,20 @@ G4double G4VSolid::EstimateCubicVolume(G4int nStat, G4double epsilon) const
EInside in;
// values needed for CalculateExtent signature
G4VoxelLimits limit; // Unlimited
G4VoxelLimits limit; // unlimited
G4AffineTransform origin;
// min max extents of pSolid along X,Y,Z
CalculateExtent(kXAxis,limit,origin,minX,maxX);
CalculateExtent(kYAxis,limit,origin,minY,maxY);
CalculateExtent(kZAxis,limit,origin,minZ,maxZ);
// limits
if(nStat < 100) { nStat = 100; }
if(epsilon > 0.01) { epsilon = 0.01; }
halfepsilon = 0.5*epsilon;
G4QuickRand(1234567890); // set seed
for(auto i = 0; i < nStat; ++i )
{
px = minX-halfepsilon+(maxX-minX+epsilon)*G4QuickRand();
@@ -350,6 +348,7 @@ G4double G4VSolid::EstimateSurfaceArea(G4int nstat, G4double ell) const
// Calculate surface area
//
G4QuickRand(1234567890); // set seed
G4int icount = 0;
for(auto i = 0; i < npoints; ++i)
{
+12 -12
View File
@@ -43,20 +43,20 @@ void G4VoxelLimits::AddLimit( const EAxis pAxis,
{
if ( pAxis == kXAxis )
{
if ( pMin > fxAxisMin ) fxAxisMin = pMin ;
if ( pMax < fxAxisMax ) fxAxisMax = pMax ;
if ( pMin > fxAxisMin ) { fxAxisMin = pMin ; }
if ( pMax < fxAxisMax ) { fxAxisMax = pMax ; }
}
else if ( pAxis == kYAxis )
{
if ( pMin > fyAxisMin ) fyAxisMin = pMin ;
if ( pMax < fyAxisMax ) fyAxisMax = pMax ;
if ( pMin > fyAxisMin ) { fyAxisMin = pMin ; }
if ( pMax < fyAxisMax ) { fyAxisMax = pMax ; }
}
else
{
assert( pAxis == kZAxis ) ;
if ( pMin > fzAxisMin ) fzAxisMin = pMin ;
if ( pMax < fzAxisMax ) fzAxisMax = pMax ;
if ( pMin > fzAxisMin ) { fzAxisMin = pMin ; }
if ( pMax < fzAxisMax ) { fzAxisMax = pMax ; }
}
}
@@ -223,18 +223,18 @@ G4int G4VoxelLimits::OutCode( const G4ThreeVector& pVec ) const
if ( IsXLimited() )
{
if ( pVec.x() < fxAxisMin ) code |= 0x01 ;
if ( pVec.x() > fxAxisMax ) code |= 0x02 ;
if ( pVec.x() < fxAxisMin ) { code |= 0x01 ; }
if ( pVec.x() > fxAxisMax ) { code |= 0x02 ; }
}
if ( IsYLimited() )
{
if ( pVec.y() < fyAxisMin ) code |= 0x04 ;
if ( pVec.y() > fyAxisMax ) code |= 0x08 ;
if ( pVec.y() < fyAxisMin ) { code |= 0x04 ; }
if ( pVec.y() > fyAxisMax ) { code |= 0x08 ; }
}
if (IsZLimited())
{
if ( pVec.z() < fzAxisMin ) code |= 0x10 ;
if ( pVec.z() > fzAxisMax ) code |= 0x20 ;
if ( pVec.z() < fzAxisMin ) { code |= 0x10 ; }
if ( pVec.z() > fzAxisMax ) { code |= 0x20 ; }
}
return code;
}
+10
View File
@@ -6,6 +6,16 @@ It must **not** be used as a substitute for writing good git commit messages!
-------------------------------------------------------------------------------
## 2025-05-15 Gabriele Cosmo (geomnav-V11-03-01)
- Reorganised and enriched comments in headers to follow Doxygen style.
- Removed declared but not implemented methods in G4VoxelNavigation,
G4ParameterisedNavigation, G4VoxelSafety and G4PathFinder.
## 2025-05-14 A. Tolosa-Delgado (geomnav-V11-03-00)
- Extended UI command /geometry/test/run to support optional overlap check
mode. Depending on the selected mode, it invokes either TestRecursiveOverlap
(default, as before) or TestOverlapInTree
## 2024-11-22 Gabriele Cosmo (geomnav-V11-02-03)
- In G4MultiLevelLocator::EstimateIntersectionPoint(), moved repeated assertion
on invalid intersection within G4DEBUG_FIELD, to avoid excess of warning
@@ -23,52 +23,64 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// class G4AuxiliaryNavServices
// G4AuxiliaryNavServices
//
// Class description:
//
// Utility class for navigation.
// History:
// - Created: Paul Kent, Aug 96
// Author: Paul Kent (CERN), August 1996
// --------------------------------------------------------------------
#ifndef G4AuxiliaryNavServices_hh
#define G4AuxiliaryNavServices_hh
#define G4AuxiliaryNavServices_hh 1
#include "G4Types.hh"
#include "G4ThreeVector.hh"
#include "G4VSolid.hh"
#include "G4AffineTransform.hh"
/**
* @brief G4AuxiliaryNavServices a utility class for navigation.
*/
class G4AuxiliaryNavServices
{
public:
public: // with description
/**
* Is the track (point, direction) inside the solid 'sampleSolid' ?
* @param[in] sampleSolid Pointer to the shape to check.
* @param[in,out] localPoint Point in local coordinates system.
* @param[in,out] globalDirection Pointer to global direction or null.
* @param[in] sampleTransform Affine transformation in space.
* @param[in] pLocatedOnEdge Flag specifying if point is located on edge.
* @returns True if we are going to enter the volume, which is the case
* if the point is inside, or the point is on the surface and
* the direction points inside or along it. Else returns false.
*/
static G4bool CheckPointOnSurface( const G4VSolid* sampleSolid,
const G4ThreeVector& localPoint,
const G4ThreeVector* globalDirection,
const G4AffineTransform& sampleTransform,
const G4bool locatedOnEdge);
static G4bool CheckPointOnSurface( const G4VSolid* sampleSolid,
const G4ThreeVector& localPoint,
const G4ThreeVector* globalDirection,
const G4AffineTransform& sampleTransform,
const G4bool locatedOnEdge);
//
// Is the track (point, direction) inside the solid 'sampleSolid' ?
// Returns true if we are going to enter the volume,
// which is the case if:
// - the point is inside
// - the point is on the surface and the direction points inside
// or along it.
// Else returns false.
/**
* Is the track (point, direction) exiting the solid 'sampleSolid' ?
* @returns True if we are going to exit the volume.
* @param[in] sampleSolid Pointer to the shape to check.
* @param[in,out] localPoint Point in local coordinates system.
* @param[in,out] globalDirection Pointer to global direction or null.
* @param[in] sampleTransform Affine transformation in space.
*/
static G4bool CheckPointExiting( const G4VSolid* sampleSolid,
const G4ThreeVector& localPoint,
const G4ThreeVector* globalDirection,
const G4AffineTransform& sampleTransform );
static G4bool CheckPointExiting( const G4VSolid* sampleSolid,
const G4ThreeVector& localPoint,
const G4ThreeVector* globalDirection,
const G4AffineTransform& sampleTransform );
//
// Is the track (point, direction) exiting the solid 'sampleSolid' ?
// Returns true if we are going to exit the volume.
static void ReportTolerances();
// Print global values of Cartesian, Radial and Angle Tolerances
/**
* Prints global values of Cartesian, Radial and Angle Tolerances.
*/
static void ReportTolerances();
};
#include "G4AuxiliaryNavServices.icc"
@@ -23,8 +23,9 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// class G4AuxiliaryNavServices Inline implementation
// Class G4AuxiliaryNavServices Inline implementation
//
// Author: Paul Kent (CERN), August 1996
// --------------------------------------------------------------------
inline G4bool
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Class G4BrentLocator
// G4BrentLocator
//
// class description:
//
@@ -32,27 +32,45 @@
// for finding the intersection point by means of a 'depth' algorithm in case
// of slow progress (intersection is not found after 100 trials).
// History:
// -------
// 27.10.08 - Tatiana Nikitina: First implementation using
// LocateIntersectionPoint() from
// G4PropagatorInField class
// Author: Tatiana Nikitina (CERN), 27 October 2008
// ---------------------------------------------------------------------------
#ifndef G4BRENTLOCATOR_HH
#define G4BRENTLOCATOR_HH
#define G4BRENTLOCATOR_HH 1
#include "G4VIntersectionLocator.hh"
/**
* @brief G4BrentLocator implements the calculation of the intersection point
* with a boundary when G4PropagationInField is used. Second order locator based
* on Brent Method for finding the intersection point by means of a 'depth'
* algorithm in case of slow progress (intersection is not found after 100
* trials).
*/
class G4BrentLocator : public G4VIntersectionLocator
{
public: // with description
public:
/**
* Constructor and Destructor.
*/
G4BrentLocator(G4Navigator *theNavigator);
// Constructor
~G4BrentLocator() override;
// Default destructor
/**
* If such an intersection exists, this method calculates the intersection
* point of the true path of the particle with the surface of the current
* volume (or of one of its daughters).
* Should use lateral displacement as measure of convergence.
* @note Changes the safety!
* @param[in] curveStartPointTangent Start point tangent track.
* @param[in] curveEndPointTangent End point tangent track.
* @param[in] trialPoint Trial point.
* @param[out] intersectPointTangent Intersection point tangent track.
* @param[out] recalculatedEndPoint Flagging if end point was recomputed.
* @param[in,out] fPreviousSafety Previous safety distance.
* @param[in,out] fPreviousSftOrigin Previous safety point origin.
* @returns Whether intersection exists or not.
*/
G4bool EstimateIntersectionPoint(
const G4FieldTrack& curveStartPointTangent, // A
const G4FieldTrack& curveEndPointTangent, // B
@@ -61,16 +79,13 @@ class G4BrentLocator : public G4VIntersectionLocator
G4bool& recalculatedEndPoint, // Out
G4double& fPreviousSafety, // In/Out
G4ThreeVector& fPreviousSftOrigin) override; // In/Out
// If such an intersection exists, this function calculates the
// intersection point of the true path of the particle with the surface
// of the current volume (or of one of its daughters).
// Should use lateral displacement as measure of convergence
private:
static const G4int max_depth = 4;
/** Used to store intermediate track values in case of too slow progress. */
G4FieldTrack* ptrInterMedFT[max_depth+1];
// Used to store intermediate tracks values in case of too slow progress
};
#endif
@@ -23,18 +23,16 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// class G4DrawVoxels
// G4DrawVoxels
//
// Class description:
//
// Utility class for the visualization of voxels in the detector geometry.
// Define G4DrawVoxelsDebug in the environment at compilation for debugging
// information printed to G4cout.
// 29/07/1999 First comitted version - L.G.
// Original author: L.G., 29 July 1999
// --------------------------------------------------------------------
#ifndef G4DrawVoxels_HH
#define G4DrawVoxels_HH
#define G4DrawVoxels_HH 1
#include "G4VisAttributes.hh"
#include "G4VoxelLimits.hh"
@@ -43,23 +41,44 @@
class G4SmartVoxelHeader;
class G4LogicalVolume;
// ***********************************************************************
/**
* @brief G4DrawVoxels is a utility class for the visualization of voxels
* in the detector geometry.
*/
class G4DrawVoxels
{
public: // with description
public:
/**
* Constructor. It initialises the members data to default colors.
*/
G4DrawVoxels();
// Constructor. It initialises the members data to default colors
// Copy constructor and assignment operator not supported (array
// fvoxelcolours ...).
/**
* Copy constructor and assignment operator not allowed.
*/
G4DrawVoxels(const G4DrawVoxels&) = delete;
G4DrawVoxels operator=(const G4DrawVoxels&) = delete;
/**
* Default Destructor.
*/
~G4DrawVoxels() = default;
// Destructor NOT virtual. Not a base class.
/**
* Draws voxels for the specified logical volume.
*/
void DrawVoxels(const G4LogicalVolume* lv) const;
/**
* Creates polyhedra for the specified logical volume.
*/
G4PlacedPolyhedronList* CreatePlacedPolyhedra(const G4LogicalVolume*) const;
/**
* Visualisation attributes control. Allow changing colors of the drawing.
*/
void SetVoxelsVisAttributes(G4VisAttributes&,
G4VisAttributes&,
G4VisAttributes&);
@@ -72,14 +91,8 @@ class G4DrawVoxels
G4VoxelLimits&,
G4PlacedPolyhedronList*) const;
G4DrawVoxels(const G4DrawVoxels&) = delete;
G4DrawVoxels operator=(const G4DrawVoxels&) = delete;
// Copy constructor and assignment operator not allowed
private:
// Member data
//
G4VisAttributes fVoxelsVisAttributes[3];
G4VisAttributes fBoundingBoxVisAttributes;
};
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// class G4ErrorPropagationNavigator
// G4ErrorPropagationNavigator
//
// Class Description:
//
@@ -31,50 +31,78 @@
// on the target surface for error propagation. It overloads ComputeStep()
// and ComputeSafety() methods.
// Created. P. Arce, September 2004
// Author: Pedro Arce (CIEMAT), September 2004
// --------------------------------------------------------------------
#ifndef G4ErrorPropagationNavigator_hh
#define G4ErrorPropagationNavigator_hh 1
#include "G4Navigator.hh"
#include "G4ThreeVector.hh"
/**
* @brief G4ErrorPropagationNavigator is a class for performing double
* navigation in the detector geometry and on the target surface for error
* propagation. It overloads ComputeStep() and ComputeSafety() methods.
*/
class G4ErrorPropagationNavigator : public G4Navigator
{
public:
/**
* Constructor and Destructor.
*/
G4ErrorPropagationNavigator() = default;
~G4ErrorPropagationNavigator() override = default;
~G4ErrorPropagationNavigator() override = default;
G4double ComputeStep (const G4ThreeVector &pGlobalPoint,
const G4ThreeVector &pDirection,
/**
* Calls the navigation in the detector geometry and then checks
* if the distance to surface is smaller than the proposed step.
* @param[in] pGlobalPoint The point in global coordinates system.
* @param[in] pDirection The normalised vector direction.
* @param[in] pCurrentProposedStepLength Current proposed step length.
* @param[in,out] newSafety New safety.
* @returns Length from current point to next boundary surface along
* @p pDirection.
*/
G4double ComputeStep (const G4ThreeVector& pGlobalPoint,
const G4ThreeVector& pDirection,
const G4double pCurrentProposedStepLength,
G4double &pNewSafety) override;
// Calls the navigation in the detector geometry and then checks
// if the distance to surface is smaller than the proposed step
G4double ComputeSafety(const G4ThreeVector &globalpoint,
/**
* Calls the navigation in the detector geometry and then checks
* if the distance to surface is smaller than the proposed safety.
* @param[in] globalpoint The point in global coordinates system.
* The point must be within the current volume.
* @param[in] pProposedMaxLength The proposed maximum length is used
* to avoid volume safety calculations.
* @param[in] keepState Flag to instruct keeping the state (default true)
* to ensure minimum side effects from the call.
* @returns Length from current point to closest boundary surface.
* The value returned is usually an underestimate.
*/
G4double ComputeSafety(const G4ThreeVector& globalpoint,
const G4double pProposedMaxLength = DBL_MAX,
const G4bool keepState = true) override;
// Calls the navigation in the detector geometry and then checks
// if the distance to surface is smaller than the proposed safety
/**
* Returns Exit Surface Normal and validity too. Can only be called if
* the Navigator's last Step has crossed a volume geometrical boundary.
* Normal points out of the volume exited and/or into the volume entered.
* @param[in] point Point in global coordinates system to compare to.
* @param[in,out] valid Flag indicating if normal is valid.
* @returns A Exit Surface Normal vector and validity too.
*/
G4ThreeVector GetGlobalExitNormal(const G4ThreeVector& point,
G4bool* valid) override;
// Return Exit Surface Normal and validity too. Can only be called if
// the Navigator's last Step has crossed a volume geometrical boundary.
// Normal points out of the volume exited and/or into the volume entered.
G4double TargetSafetyFromPoint( const G4ThreeVector &pGlobalpoint );
// Isotropic safety for 'Target'
//-- NOT implemented, as it is difficult to define the coordinate system:
// G4ThreeVector GetLocalExitNormal(G4bool* valid);
// G4ThreeVector GetLocalExitNormalAndCheck(const G4ThreeVector& point,
// G4bool* valid);
// Convention:
// The *local* normal is in the coordinate system of the *final* volume.
/**
* Computes the isotropic safety for 'Target'.
* @param[in] pGlobalpoint Point in global coordinates system.
* @returns The isotropic safety value.
*/
G4double TargetSafetyFromPoint( const G4ThreeVector& pGlobalpoint );
};
#endif
@@ -23,57 +23,80 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// class G4GeomTestVolume
// G4GeomTestVolume
//
// Class description:
//
// Checks for inconsistencies in the geometric boundaries of a physical
// volume and the boundaries of all its immediate daughters.
// Author: G.Cosmo, CERN
// Author: Gabriele Cosmo (CERN), 22 August 2013
// --------------------------------------------------------------------
#ifndef G4GeomTestVolume_hh
#define G4GeomTestVolume_hh
#define G4GeomTestVolume_hh 1
#include "G4ThreeVector.hh"
class G4VPhysicalVolume;
class G4GeomTestLogger;
/**
* @brief G4GeomTestVolume allows to check for inconsistencies in the
* geometric boundaries of a physical volume and the boundaries of all
* its immediate daughters.
*/
class G4GeomTestVolume
{
public: // with description
public:
/**
* Constructor and Destructor.
*/
G4GeomTestVolume( G4VPhysicalVolume *theTarget,
G4double theTolerance = 0.0, // mm
G4int numberOfPoints = 10000,
G4bool theVerbosity = true);
~G4GeomTestVolume();
// Constructor and destructor
/**
* Gets/Sets error tolerance (default set to 0*mm).
*/
G4double GetTolerance() const;
void SetTolerance(G4double tolerance);
// Get/Set error tolerance (default set to 0*mm)
/**
* Gets/Sets number of points to check (default set to 10000).
*/
G4int GetResolution() const;
void SetResolution(G4int points);
// Get/Set number of points to check (default set to 10000)
/**
* Gets/Sets verbosity mode (default set to true).
*/
G4bool GetVerbosity() const;
void SetVerbosity(G4bool verbosity);
// Get/Set verbosity mode (default set to true)
/**
* Get/Set maximum number of errors to report (default set to 1).
*/
G4int GetErrorsThreshold() const;
void SetErrorsThreshold(G4int max);
// Get/Set maximum number of errors to report (default set to 1)
/**
* Checks for overlaps in the volume tree without duplication in
* identical logical volumes.
*/
void TestOverlapInTree() const;
// Check overlaps in the volume tree without
// dublication in identical logical volumes
/**
* Activates overlaps check, propagating recursively to the daughters,
* with possibility of specifying the initial level in the volume tree
* and the depth (default is the whole tree).
* @note Depending on the complexity of the geometry, this may require
* long computational time.
*/
void TestRecursiveOverlap( G4int sLevel=0, G4int depth=-1 );
// Activate overlaps check, propagating recursively to the daughters,
// with possibility of specifying the initial level in the volume tree
// and the depth (default is the whole tree).
// Be careful: depending on the complexity of the geometry, this
// could require long computational time
private:
@@ -23,41 +23,52 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// class G4GeometryMessenger
// G4GeometryMessenger
//
// Class description:
//
// A messenger defining commands for debugging, verifying
// and controlling the detector geometry and navigation.
// Author: G.Cosmo, CERN.
// Author: Gabriele Cosmo (CERN), 24 October 2001.
// --------------------------------------------------------------------
#ifndef G4GeometryMessenger_hh
#define G4GeometryMessenger_hh
#define G4GeometryMessenger_hh 1
#include "G4Types.hh"
#include "G4UImessenger.hh"
#include "G4ThreeVector.hh"
#include <vector>
class G4UIdirectory;
class G4UIcommand;
class G4UIcmdWithoutParameter;
class G4UIcmdWithABool;
class G4UIcmdWithAnInteger;
class G4UIcmdWithADoubleAndUnit;
class G4UIcmdWithAString;
class G4TransportationManager;
class G4GeomTestVolume;
#include <vector>
/**
* @brief G4GeometryMessenger is a messenger defining commands for debugging,
* verifying and controlling the detector geometry and navigation.
*/
class G4GeometryMessenger : public G4UImessenger
{
public: // with description
public:
/**
* Constructor and Destructor.
*/
G4GeometryMessenger(G4TransportationManager* tman);
~G4GeometryMessenger() override;
// Constructor and destructor
/**
* Sets/gets values for UI command.
*/
void SetNewValue( G4UIcommand* command, G4String newValues ) override;
G4String GetCurrentValue( G4UIcommand* command ) override;
@@ -70,10 +81,18 @@ class G4GeometryMessenger : public G4UImessenger
void SetCheckMode(const G4String& newValue);
void SetPushFlag(const G4String& newValue);
void RecursiveOverlapTest();
void TreeOverlapTest();
struct OverlapMode
{
inline static const G4String placed = "placed";
inline static const G4String logical = "logical";
};
G4UIdirectory *geodir, *navdir, *testdir;
G4UIcmdWithABool *chkCmd, *pchkCmd, *verCmd, *parCmd;
G4UIcmdWithoutParameter *recCmd, *resCmd;
G4UIcmdWithoutParameter *resCmd;
G4UIcmdWithAString *recCmd;
G4UIcmdWithADoubleAndUnit *tolCmd;
G4UIcmdWithAnInteger *verbCmd, *rslCmd, *rcsCmd, *rcdCmd, *errCmd;
@@ -23,7 +23,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// class G4GlobalMagFieldMessenger
// G4GlobalMagFieldMessenger
//
// Class description:
//
@@ -38,7 +38,7 @@
// The field value can be changed either interactively via
// the UI command or via SetFieldValue() function.
// Author: Ivana Hrivnacova, 28/08/2013 (ivana@ipno.in2p3.fr)
// Author: Ivana Hrivnacova (IN2P3/IJCLab Orsay), 28 August 2013
// --------------------------------------------------------------------
#ifndef G4GlobalMagFieldMessenger_hh
#define G4GlobalMagFieldMessenger_hh 1
@@ -51,19 +51,39 @@ class G4UIdirectory;
class G4UIcmdWith3VectorAndUnit;
class G4UIcmdWithAnInteger;
/**
* @brief G4GlobalMagFieldMessenger, a global uniform magnetic field messenger
* class. It creates/deletes the global uniform magnetic field and
* activates/inactivates it according to the set field value.
* The field value can be changed either interactively via the UI command or
* via the SetFieldValue() function.
*/
class G4GlobalMagFieldMessenger : public G4UImessenger
{
public: // with description
public:
/**
* Constructor and Destructor.
*/
G4GlobalMagFieldMessenger(const G4ThreeVector& value = G4ThreeVector());
~G4GlobalMagFieldMessenger() override;
/**
* Setter for UI command.
*/
void SetNewValue(G4UIcommand*, G4String) override;
void SetFieldValue(const G4ThreeVector& value);
/**
* Setter and accessor for the field value.
*/
void SetFieldValue(const G4ThreeVector& value);
G4ThreeVector GetFieldValue() const;
inline void SetVerboseLevel(G4int verboseLevel);
/**
* Verbosity control.
*/
inline void SetVerboseLevel(G4int verboseLevel);
inline G4int GetVerboseLevel() const;
private:
@@ -78,12 +98,18 @@ class G4GlobalMagFieldMessenger : public G4UImessenger
G4UIcmdWithAnInteger* fSetVerboseCmd = nullptr;
};
// --------------------------------------------------------------------
// inline functions
// --------------------------------------------------------------------
inline void G4GlobalMagFieldMessenger::SetVerboseLevel(G4int verboseLevel)
{ fVerboseLevel = verboseLevel; }
inline void G4GlobalMagFieldMessenger::SetVerboseLevel(G4int verboseLevel)
{
fVerboseLevel = verboseLevel;
}
inline G4int G4GlobalMagFieldMessenger::GetVerboseLevel() const
{ return fVerboseLevel; }
{
return fVerboseLevel;
}
#endif
@@ -30,70 +30,90 @@
// Aggregate the records of changes in an endpoint of a locator.
// Its key use is in playing these back in case of a problem.
// Author: John Apostolakis, 04.09.19 - First version
// Author: John Apostolakis (CERN), 04 September 2019
// --------------------------------------------------------------------
#ifndef G4LOCATOR_CHANGE_LOGGER_HH
#define G4LOCATOR_CHANGE_LOGGER_HH
#define G4LOCATOR_CHANGE_LOGGER_HH 1
#include <vector>
#include "G4LocatorChangeRecord.hh"
#include "G4FieldTrack.hh"
/**
* @brief G4LocatorChangeLogger aggregates the records of changes in an
* endpoint of a locator. Its key use is in playing these back in case of
* a problem.
*/
class G4LocatorChangeLogger : public std::vector<G4LocatorChangeRecord>
{
public:
G4LocatorChangeLogger( const std::string& name ) : fName(name) {}
/**
* Constructor.
*/
G4LocatorChangeLogger( const std::string& name );
void AddRecord( G4LocatorChangeRecord && chngRecord );
void AddRecord( const G4LocatorChangeRecord & chngRecord );
/**
* Move or add a record.
*/
inline void AddRecord( G4LocatorChangeRecord && chngRecord );
inline void AddRecord( const G4LocatorChangeRecord & chngRecord );
// Create a new record with full information
inline
void AddRecord( G4LocatorChangeRecord::EChangeLocation codeLocation,
G4int iter,
unsigned int count,
const G4FieldTrack & fieldTrack );
/**
* Create a new record with full information.
*/
inline void AddRecord( G4LocatorChangeRecord::EChangeLocation codeLocation,
G4int iter, unsigned int count,
const G4FieldTrack& fieldTrack );
/**
* Streaming operator dumping record.
*/
friend std::ostream& operator << ( std::ostream& os,
const G4LocatorChangeLogger& logR );
/**
* Streams object contents to an output stream.
*/
std::ostream& StreamInfo(std::ostream& os) const;
/**
* Prints the changes in start, end points in columns. One event per row.
*/
static std::ostream& ReportEndChanges ( std::ostream& os,
const G4LocatorChangeLogger& startA,
const G4LocatorChangeLogger& endB );
// Print the changes in start, end points in columns
// One event per row
private:
const std::string fName;
const std::string fName;
};
// --------------
// --------------------------------------------------------------------
// Inline methods
// --------------
// --------------------------------------------------------------------
void G4LocatorChangeLogger::
AddRecord( G4LocatorChangeRecord::EChangeLocation codeLocation,
G4int iter, unsigned int count,
const G4FieldTrack & fieldTrack )
{
this->push_back(G4LocatorChangeRecord(codeLocation, iter, count, fieldTrack));
push_back(G4LocatorChangeRecord(codeLocation, iter, count, fieldTrack));
}
inline
void G4LocatorChangeLogger::
AddRecord( const G4LocatorChangeRecord& chngRecord )
{
this->push_back( chngRecord );
push_back( chngRecord );
}
inline
void G4LocatorChangeLogger::
AddRecord( G4LocatorChangeRecord && chngRecord )
{
this->push_back( chngRecord );
push_back( chngRecord );
}
#endif
@@ -30,14 +30,19 @@
// Record the changes in an endpoint of a locator.
// Its key use is in playing these back in case of a problem.
// Author: John Apostolakis, 27.08.19 - First version
// Author: John Apostolakis (CERN), 27 August 2019
// --------------------------------------------------------------------
#ifndef G4LOCATOR_CHANGE_RECORD_HH
#define G4LOCATOR_CHANGE_RECORD_HH
#define G4LOCATOR_CHANGE_RECORD_HH 1
#include <vector>
#include "G4FieldTrack.hh"
/**
* @brief G4LocatorChangeRecord records the changes in an endpoint of a locator.
* Its key use is in playing these back in case of a problem.
*/
class G4LocatorChangeRecord
{
public:
@@ -48,36 +53,41 @@ class G4LocatorChangeRecord
kInsertingMidPoint, kRecalculatedBagn, // 2
kLevelPop };
static const char* fNameChangeLocation[];
static const char* GetNameChangeLocation( EChangeLocation );
/**
* Constructor.
*/
G4LocatorChangeRecord( EChangeLocation codeLocation,
G4int iter,
unsigned int count,
const G4FieldTrack& fieldTrack )
: fCodeLocation( codeLocation), fIteration(iter), fEventCount(count),
fFieldTrack( fieldTrack ) {}
const G4FieldTrack& fieldTrack );
/**
* Default copy and move constructors.
*/
G4LocatorChangeRecord( const G4LocatorChangeRecord & ) = default;
G4LocatorChangeRecord( G4LocatorChangeRecord && ) = default;
// No set methods -> create a new record for each entry (more reliable)
// void SetLocation( EChangeLocation loc ) { fCodeLocation= loc; }
// void SetLength( double len ) { fLength= len; }
// void SetCount( int cnt ) { fEventCount= cnt; }
// void SetIteration( int iter ) { fIteration= iter; }
/**
* Accessors.
*/
inline EChangeLocation GetLocation() const { return fCodeLocation; }
inline unsigned int GetCount() const { return fEventCount; }
inline G4int GetIteration() const { return fIteration; }
inline G4double GetLength() const { return fFieldTrack.GetCurveLength(); }
/**
* Streaming operators, using StreamInfo().
*/
friend std::ostream& operator<< ( std::ostream& os,
const G4LocatorChangeRecord& r );
// Streaming operator, using StreamInfo().
friend std::ostream& operator<< ( std::ostream& os,
const std::vector<G4LocatorChangeRecord> & vecR );
/**
* Streams object contents to an output stream.
*/
std::ostream& StreamInfo(std::ostream& os) const;
static std::ostream& ReportVector ( std::ostream& os,
@@ -88,8 +98,11 @@ class G4LocatorChangeRecord
const std::vector<G4LocatorChangeRecord> & startA,
const std::vector<G4LocatorChangeRecord> & endB );
static const char* GetNameChangeLocation( EChangeLocation );
private:
static const char* fNameChangeLocation[];
EChangeLocation fCodeLocation = kInvalidCL;
G4int fIteration = -1;
unsigned int fEventCount = 0;
@@ -23,9 +23,9 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Class G4MultiLevelLocator
// G4MultiLevelLocator
//
// class description:
// Class description:
//
// Implementing the calculation of the intersection point with a boundary when
// PropagationInField is used. Derived from method LocateIntersectionPoint()
@@ -33,66 +33,88 @@
// intersection point by means of a 'depth' algorithm in case of slow progress
// (intersection is not found after 100 trials).
// History:
// -------
// 27.10.08 - Tatiana Nikitina: Derived from LocateIntersectionPoint() from
// G4PropagatorInField class
// Author: Tatiana Nikitina (CERN), 27 October 2008
// ---------------------------------------------------------------------------
#ifndef G4MULTILEVELLOCATOR_HH
#define G4MULTILEVELLOCATOR_HH
#define G4MULTILEVELLOCATOR_HH 1
#include "G4VIntersectionLocator.hh"
/**
* @brief G4MultiLevelLocator implements the calculation of the intersection
* point with a boundary when G4PropagationInField is used. Derived from method
* LocateIntersectionPoint() from G4PropagatorInField, it is based on a linear
* method for finding the intersection point by means of a 'depth' algorithm
* in case of slow progress (intersection is not found after 100 trials).
*/
class G4MultiLevelLocator : public G4VIntersectionLocator
{
public: // with description
public:
G4MultiLevelLocator(G4Navigator *theNavigator);
// Constructor
~G4MultiLevelLocator() override;
// Default destructor
/**
* Constructor and Destructor.
*/
G4MultiLevelLocator(G4Navigator *theNavigator);
~G4MultiLevelLocator() override;
G4bool EstimateIntersectionPoint(
const G4FieldTrack& curveStartPointTangent, // A
const G4FieldTrack& curveEndPointTangent, // B
const G4ThreeVector& trialPoint, // E
G4FieldTrack& intersectPointTangent, // Output
G4bool& recalculatedEndPoint, // Out
G4double& fPreviousSafety, // In/Out
G4ThreeVector& fPreviousSftOrigin) override; // In/Out
// If such an intersection exists, this function calculates the
// intersection point of the true path of the particle with the surface
// of the current volume (or of one of its daughters).
// Should use lateral displacement as measure of convergence
/**
* If such an intersection exists, this method calculates the intersection
* point of the true path of the particle with the surface of the current
* volume (or of one of its daughters).
* Should use lateral displacement as measure of convergence.
* @param[in] curveStartPointTangent Start point tangent track.
* @param[in] curveEndPointTangent End point tangent track.
* @param[in] trialPoint Trial point.
* @param[out] intersectPointTangent Intersection point tangent track.
* @param[out] recalculatedEndPoint Flagging if end point was recomputed.
* @param[in,out] fPreviousSafety Previous safety distance.
* @param[in,out] fPreviousSftOrigin Previous safety point origin.
* @returns Whether intersection exists or not.
*/
G4bool EstimateIntersectionPoint(
const G4FieldTrack& curveStartPointTangent, // A
const G4FieldTrack& curveEndPointTangent, // B
const G4ThreeVector& trialPoint, // E
G4FieldTrack& intersectPointTangent, // Output
G4bool& recalculatedEndPoint, // Out
G4double& fPreviousSafety, // In/Out
G4ThreeVector& fPreviousSftOrigin) override; // In/Out
void ReportStatistics();
/**
* Dumps statistics.
*/
void ReportStatistics();
inline void SetMaxSteps(unsigned int valMax) { fMaxSteps= valMax; }
inline void SetWarnSteps(unsigned int valWarn) { fWarnSteps= valWarn; }
/**
* Setters.
*/
inline void SetMaxSteps(unsigned int valMax) { fMaxSteps = valMax; }
inline void SetWarnSteps(unsigned int valWarn) { fWarnSteps = valWarn; }
private:
private:
void ReportFieldValue( const G4FieldTrack& locationPV,
const char* nameLoc,
const G4EquationOfMotion* equation );
void ReportFieldValue( const G4FieldTrack& locationPV,
const char* nameLoc,
const G4EquationOfMotion* equation );
// Invariants -- parameters
// ====================================
static const G4int max_depth = 10;
unsigned int fMaxSteps = 10000; // Effort abandoned; signal is looping
unsigned int fWarnSteps = 1000; // Warn about many steps (but succeeded)
// Invariants -- parameters
// ====================================
static const G4int max_depth = 10;
unsigned int fMaxSteps = 10000; // Effort abandoned; signal is looping
unsigned int fWarnSteps = 1000; // Warn about many steps (but succeeded)
// State - varies during simulation
// ====================================
G4FieldTrack* ptrInterMedFT[max_depth+1];
// Used to store intermediate tracks values in case of too slow progress
unsigned long int fNumCalls = 0;
unsigned long int fNumAdvanceFull = 0,
fNumAdvanceGood = 0,
fNumAdvanceTrials = 0;
// Counters for statistics & debugging
// State - varies during simulation
// ====================================
G4FieldTrack* ptrInterMedFT[max_depth+1]; // Used to store intermediate
// tracks values in case of too
// slow progress
// Counters for statistics & debugging
// ====================================
unsigned long int fNumCalls = 0;
unsigned long int fNumAdvanceFull = 0,
fNumAdvanceGood = 0,
fNumAdvanceTrials = 0;
};
#endif
@@ -23,18 +23,17 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// class G4MultiNavigator
// G4MultiNavigator
//
// Class description:
//
// Utility class for polling the navigators of several geometries to
// identify the next boundary.
// History:
// - Created. John Apostolakis, November 2006
// Author: John Apostolakis (CERN), November 2006
// --------------------------------------------------------------------
#ifndef G4MULTINAVIGATOR_HH
#define G4MULTINAVIGATOR_HH
#define G4MULTINAVIGATOR_HH 1
#include <iostream>
@@ -51,152 +50,243 @@ enum ELimited { kDoNot,kUnique,kSharedTransport,kSharedOther,kUndefLimited };
class G4TransportationManager;
class G4VPhysicalVolume;
/**
* @brief G4MultiNavigator is a utility class for polling the navigators
* of several geometries to identify the next boundary.
*/
class G4MultiNavigator : public G4Navigator
{
public: // with description
public:
friend std::ostream& operator << (std::ostream& os, const G4Navigator& n);
friend std::ostream& operator << (std::ostream& os, const G4Navigator& n);
G4MultiNavigator();
// Constructor - initialisers and setup.
/**
* Constructor and default Destructor.
*/
G4MultiNavigator();
~G4MultiNavigator() override = default;
~G4MultiNavigator() override;
// Destructor. No actions.
/**
* Computes the distance to the next boundary of any geometry.
* @param[in] pGlobalPoint The point in global coordinates system.
* @param[in] pDirection The normalised vector direction.
* @param[in] pCurrentProposedStepLength Current proposed step length.
* @param[in,out] newSafety New safety.
* @returns Length from current point to next boundary surface along
* @p pDirection.
*/
G4double ComputeStep( const G4ThreeVector& pGlobalPoint,
const G4ThreeVector& pDirection,
const G4double pCurrentProposedStepLength,
G4double& pNewSafety ) override;
G4double ComputeStep( const G4ThreeVector& pGlobalPoint,
const G4ThreeVector& pDirection,
const G4double pCurrentProposedStepLength,
G4double& pNewSafety ) override;
// Return the distance to the next boundary of any geometry
/**
* Gets values for a single geometry.
* @param[in] navigatorId The navigator identifier.
* @param[in,out] pnewSafety New safety for this geometry.
* @param[in,out] minStepLast The last minimum step returned.
* @param[in,out] limitedStep The step characterisation returned.
* @returns The step size for the geometry associated to 'navigatorId'.
*/
G4double ObtainFinalStep( G4int navigatorId,
G4double& pNewSafety, // for this geom
G4double& minStepLast,
ELimited& limitedStep );
G4double ObtainFinalStep( G4int navigatorId,
G4double& pNewSafety, // for this geom
G4double& minStepLast,
ELimited& limitedStep );
// Get values for a single geometry
/**
* Finds which geometries are registered for this particles, and keeps info.
*/
void PrepareNavigators();
void PrepareNavigators();
// Find which geometries are registered for this particles, and keep info
void PrepareNewTrack( const G4ThreeVector& position,
const G4ThreeVector direction );
// Prepare Navigators and locate
/**
* Prepares Navigators and locates.
* @param[in] position The position point in global coordinates system.
* @param[in] direction The normalised vector direction.
*/
void PrepareNewTrack( const G4ThreeVector& position,
const G4ThreeVector direction );
G4VPhysicalVolume* ResetHierarchyAndLocate( const G4ThreeVector& point,
const G4ThreeVector& direction,
const G4TouchableHistory& h ) override;
// Reset the geometrical hierarchy for all geometries.
// Use the touchable history for the first (mass) geometry.
// Return the volume in the first (mass) geometry.
//
// Important Note: In order to call this the geometries MUST be closed.
/**
* Resets the geometrical hierarchy for all geometries.
* Use the touchable history for the first (mass) geometry.
* @note In order to call this the geometries MUST be closed.
* @param[in] point The point in global coordinates system.
* @param[in] direction The normalised vector direction.
* @param[in] h The touchable history to be used for initialisation.
* @returns The pointer to the volume in the first (mass) geometry.
*/
G4VPhysicalVolume* ResetHierarchyAndLocate( const G4ThreeVector& point,
const G4ThreeVector& direction,
const G4TouchableHistory& h ) override;
G4VPhysicalVolume* LocateGlobalPointAndSetup( const G4ThreeVector& point,
const G4ThreeVector* direction = nullptr,
const G4bool pRelativeSearch = true,
const G4bool ignoreDirection = true) override;
// Locate in all geometries.
// Return the volume in the first (mass) geometry
// Maintain vector of other volumes, to be returned separately
//
// Important Note: In order to call this the geometry MUST be closed.
/**
* Locates the point in all geometries.
* Maintains a vector of other volumes, to be returned separately.
* @note In order to call this the geometry MUST be closed.
* @param[in] point The point in global coordinates system.
* @param[in] direction The normalised vector direction.
* @param[in] pRelativeSearch Flag to specify where search starts from.
* @param[in] ignoreDirection Flag to specify if to use direction or not.
* @returns The volume in the first (mass) geometry.
*/
G4VPhysicalVolume* LocateGlobalPointAndSetup( const G4ThreeVector& point,
const G4ThreeVector* direction = nullptr,
const G4bool pRelativeSearch = true,
const G4bool ignoreDirection = true) override;
void LocateGlobalPointWithinVolume( const G4ThreeVector& position ) override;
// Relocate in all geometries for point that has not changed volume
// (ie is within safety in all geometries or is distance less that
// along the direction of a computed step.
/**
* Relocates in all geometries for point that has not changed volume,
* i.e. is within safety in all geometries or its distance is less that
* along the direction of a computed step.
* @param[in] position The position point in global coordinates system.
*/
void LocateGlobalPointWithinVolume( const G4ThreeVector& position ) override;
G4double ComputeSafety( const G4ThreeVector& globalpoint,
const G4double pProposedMaxLength = DBL_MAX,
const G4bool keepState = false ) override;
// Calculate the isotropic distance to the nearest boundary
// in any geometry from the specified point in the global coordinate
// system. The geometry must be closed.
/**
* Calculates the isotropic distance to the nearest boundary in any
* geometry from the specified point in the global coordinates system.
* @note The geometry must be closed.
* @param[in] globalpoint The point in global coordinates system.
* The point must be within the current volume.
* @param[in] pProposedMaxLength The proposed maximum length is used
* to avoid volume safety calculations.
* @param[in] keepState Flag to instruct keeping the state (default false)
* to ensure minimum side effects from the call.
* @returns Length from current point to closest boundary surface.
* The value returned is usually an underestimate.
*/
G4double ComputeSafety( const G4ThreeVector& globalpoint,
const G4double pProposedMaxLength = DBL_MAX,
const G4bool keepState = false ) override;
G4TouchableHandle CreateTouchableHistoryHandle() const override;
// Returns a reference counted handle to a touchable history.
/**
* Returns a reference counted handle to a touchable history.
*/
G4TouchableHandle CreateTouchableHistoryHandle() const override;
G4ThreeVector GetLocalExitNormal( G4bool* obtained ) override; // const
G4ThreeVector GetLocalExitNormalAndCheck( const G4ThreeVector &E_Pt,
G4bool* obtained ) override; // const
G4ThreeVector GetGlobalExitNormal( const G4ThreeVector &E_Pt,
G4bool* obtained ) override; // const
// Return Exit Surface Normal and validity too.
// Can only be called if the Navigator's last Step either
// - has just crossed a volume geometrical boundary and relocated, or
// - has arrived at a boundary in a ComputeStep
// It returns the Normal to the surface pointing out of the volume that
// was left behind and/or into the volume that was entered.
// Convention:x
// The *local* normal is in the coordinate system of the *final* volume.
// Restriction:
// Normals are not available for replica volumes (returns obtained= false)
/**
* Obtains the Normal vector to a surface (in local coordinates)
* pointing out of previous volume and into current volume
* Convention: the *local* normal is in the coordinate system of the
* *final* volume. The method takes full care about how to calculate
* this normal, but if the surfaces are not convex it will return
* valid=false.
* @param[in,out] obtained Flag indicating if normal is valid.
* @returns A Exit Surface Normal vector and validity too.
*/
G4ThreeVector GetLocalExitNormal( G4bool* obtained ) override;
public: // without description
/**
* Obtains the Normal vector to a surface (in local coordinates)
* pointing out of previous volume and into current volume, and
* checks the current point against expected 'local' value.
* Convention: the *local* normal is in the coordinate system of the
* *final* volume. The method takes full care about how to calculate
* this normal, but if the surfaces are not convex it will return
* valid=false.
* @param[in] point Point in global coordinates system to compare to.
* @param[in,out] obtained Flag indicating if normal is valid.
* @returns A Exit Surface Normal vector and validity too.
*/
G4ThreeVector GetLocalExitNormalAndCheck( const G4ThreeVector& point,
G4bool* obtained ) override;
inline G4Navigator* GetNavigator( G4int n ) const
{
if( (n>fNoActiveNavigators) || (n<0) ) { n=0; }
return fpNavigator[n];
}
/**
* Obtains the Normal vector to a surface (in global coordinates)
* pointing out of previous volume and into current volume
* The method takes full care about how to calculate the normal,
* but if the surfaces are not convex it will return valid=false.
* @param[in] point Point in global coordinates system to compare to.
* @param[in,out] obtained Flag indicating if normal is valid.
* @returns A Exit Surface Normal vector and validity too.
*/
G4ThreeVector GetGlobalExitNormal( const G4ThreeVector& point,
G4bool* obtained ) override;
protected: // with description
/**
* Returns a pointer to a navigator, given its index.
*/
inline G4Navigator* GetNavigator( G4int n ) const;
void ResetState() override;
// Utility method to reset the navigator state machine.
protected:
void SetupHierarchy() override;
// Renavigate & reset hierarchy described by current history
// o Reset volumes
// o Recompute transforms and/or solids of replicated/parameterised
// volumes.
/**
* Utility method to reset the navigator state machine.
*/
void ResetState() override;
void WhichLimited(); // Flag which processes limited the step
void PrintLimited(); // Auxiliary, debugging printing
void CheckMassWorld();
/**
* Renavigates & resets hierarchy described by the current history,
* i.e. resets volumes and recomputes transforms and/or solids of
* replicated/parameterised volumes.
*/
void SetupHierarchy() override;
private:
/**
* Flags which processes limited the step.
*/
void WhichLimited();
// STATE Information
/**
* Auxiliary, debugging printing.
*/
void PrintLimited();
G4int fNoActiveNavigators = 0;
static const G4int fMaxNav = 16;
G4VPhysicalVolume* fLastMassWorld = nullptr;
/**
* Checks if mass world pointed has been changed => issues and exception.
*/
void CheckMassWorld();
G4Navigator* fpNavigator[fMaxNav];
// Global state (retained during stepping for one track
private:
// State after a step computation
//
ELimited fLimitedStep[fMaxNav];
G4bool fLimitTruth[fMaxNav];
G4double fCurrentStepSize[fMaxNav];
G4double fNewSafety[ fMaxNav ]; // Safety for starting point
G4int fNoLimitingStep = -1; // How many geometries limited the step
G4int fIdNavLimiting = -1; // Id of Navigator limiting step
// STATE Information
// Lowest values - determine step length, and safety
//
G4double fMinStep = -kInfinity; // As reported by Navigators
G4double fMinSafety = -kInfinity;
G4double fTrueMinStep = -kInfinity; // Corrected if fMinStep>=proposed
G4int fNoActiveNavigators = 0;
static const G4int fMaxNav = 16;
G4VPhysicalVolume* fLastMassWorld = nullptr;
// State after calling 'locate'
//
G4VPhysicalVolume* fLocatedVolume[fMaxNav];
G4ThreeVector fLastLocatedPosition;
/** Global state (retained during stepping for one track). */
G4Navigator* fpNavigator[fMaxNav];
// Cache of safety information
//
G4ThreeVector fSafetyLocation;
// point where ComputeSafety is called
G4double fMinSafety_atSafLocation = -1.0;
// - corresponding value of safety
G4ThreeVector fPreStepLocation;
// point where last ComputeStep called
G4double fMinSafety_PreStepPt = -1.0;
// - corresponding value of safety
// State after a step computation
//
ELimited fLimitedStep[fMaxNav];
G4bool fLimitTruth[fMaxNav];
G4double fCurrentStepSize[fMaxNav];
G4double fNewSafety[ fMaxNav ]; // Safety for starting point
G4int fNoLimitingStep = -1; // How many geometries limited the step
G4int fIdNavLimiting = -1; // Id of Navigator limiting step
G4TransportationManager* pTransportManager; // Cache for frequent use
// Lowest values - determine step length, and safety
//
G4double fMinStep = -kInfinity; // As reported by Navigators
G4double fMinSafety = -kInfinity;
G4double fTrueMinStep = -kInfinity; // Corrected if fMinStep>=proposed
// State after calling 'locate'
//
G4VPhysicalVolume* fLocatedVolume[fMaxNav];
G4ThreeVector fLastLocatedPosition;
// Cache of safety information
//
G4ThreeVector fSafetyLocation; // point where ComputeSafety() is called
G4double fMinSafety_atSafLocation = -1.0; // - corresponding value of safety
G4ThreeVector fPreStepLocation; // point where last ComputeStep() called
G4double fMinSafety_PreStepPt = -1.0; // - corresponding value of safety
G4TransportationManager* pTransportManager; // Cache for frequent use
};
// --------------------------------------------------------------------
// Inline methods
// --------------------------------------------------------------------
inline G4Navigator* G4MultiNavigator::GetNavigator( G4int n ) const
{
if( (n>fNoActiveNavigators) || (n<0) ) { n=0; }
return fpNavigator[n];
}
#endif
@@ -23,18 +23,17 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// class G4NavigationLogger
// G4NavigationLogger
//
// Class description:
//
// Simple utility class for use by navigation systems
// for verbosity and check-mode.
// History:
// - Created. Gabriele Cosmo, November 2010
// Author: Gabriele Cosmo (CERN), November 2010
// --------------------------------------------------------------------
#ifndef G4NAVIGATIONLOGGER_HH
#define G4NAVIGATIONLOGGER_HH
#define G4NAVIGATIONLOGGER_HH 1
#include "G4NavigationHistory.hh"
#include "G4VPhysicalVolume.hh"
@@ -42,26 +41,41 @@
#include "G4VSolid.hh"
#include "G4ThreeVector.hh"
/**
* @brief G4NavigationLogger is a simple utility class for use by the
* navigation systems for verbosity and check-mode.
*/
class G4NavigationLogger
{
public: // with description
public:
/**
* Constructor and Destructor.
*/
G4NavigationLogger(const G4String& id);
~G4NavigationLogger();
/**
* Reports about first check - mother safety.
*/
void PreComputeStepLog (const G4VPhysicalVolume* motherPhysical,
G4double motherSafety,
const G4ThreeVector& localPoint) const;
// Report about first check - mother safety
/**
* Reports about a candidate daughter.
*/
void AlongComputeStepLog(const G4VSolid* sampleSolid,
const G4ThreeVector& samplePoint,
const G4ThreeVector& sampleDirection,
const G4ThreeVector& localDirection,
G4double sampleSafety,
G4double sampleStep) const;
// Report about a candidate daughter
/**
* Checks suspicious distance to a candidate daughter.
*/
void CheckDaughterEntryPoint(const G4VSolid* sampleSolid,
const G4ThreeVector& samplePoint,
const G4ThreeVector& sampleDirection,
@@ -70,62 +84,79 @@ class G4NavigationLogger
const G4ThreeVector& localDirection,
G4double motherStep,
G4double sampleStep) const;
// Check suspicious distance to a candidate daughter
/**
* Reports exit distance from mother.
*/
void PostComputeStepLog (const G4VSolid* motherSolid,
const G4ThreeVector& localPoint,
const G4ThreeVector& localDirection,
G4double motherStep,
G4double motherSafety) const;
// Report exit distance from mother
/**
* Reports about safety computation.
*/
void ComputeSafetyLog (const G4VSolid* solid,
const G4ThreeVector& point,
G4double safety,
G4bool isMotherVolume, // For labeling
G4int banner= -1) const;
// Report about safety computation (daughter?)
/**
* Reports about a new minimum distance to candidate daughter.
*/
void PrintDaughterLog (const G4VSolid* sampleSolid,
const G4ThreeVector& samplePoint,
G4double sampleSafety,
G4bool onlySafety,
const G4ThreeVector& sampleDirection,
G4double sampleStep ) const;
// Report about a new minimum distance to candidate daughter
G4double sampleStep) const;
/**
* Reports issue with normal from Solid - for ComputeStep().
*/
G4bool CheckAndReportBadNormal(const G4ThreeVector& unitNormal,
const G4ThreeVector& localPoint,
const G4ThreeVector& localDirection,
G4double step,
const G4VSolid* solid,
const char* msg ) const;
// Report issue with normal from Solid - for ComputeStep()
const char* msg) const;
/**
* Reports issue with normal from Rotation - for ComputeStep().
*/
G4bool CheckAndReportBadNormal(const G4ThreeVector& unitNormal,
const G4ThreeVector& originalNormal,
const G4RotationMatrix& rotationM,
const char* msg ) const;
// Report issue with normal from Rotation - for ComputeStep()
const char* msg) const;
/**
* Reports if point wrongly located outside mother volume.
*/
void ReportOutsideMother(const G4ThreeVector& localPoint,
const G4ThreeVector& localDirection,
const G4VPhysicalVolume* motherPV,
G4double tDist = 30.0*CLHEP::cm ) const;
// Report if point wrongly located outside mother volume
G4double tDist = 30.0*CLHEP::cm) const;
void ReportVolumeAndIntersection( std::ostream& ostrm,
/**
* Auxiliary method to report information about volume
* and position/direction
*/
void ReportVolumeAndIntersection(std::ostream& ostrm,
const G4ThreeVector& localPoint,
const G4ThreeVector& localDirection,
const G4VPhysicalVolume* physical ) const;
// Auxiliary method to report information about volume
// and position/direction
const G4VPhysicalVolume* physical) const;
public: // without description
/**
* Verbosity control.
*/
inline G4int GetVerboseLevel() const { return fVerbose; }
inline void SetVerboseLevel(G4int level) { fVerbose = level; }
/**
* Accessors/modifiers.
*/
inline G4double GetMinTriggerDistance() const {return fMinTriggerDistance;}
inline void SetMinTriggerDistance(G4double d) {fMinTriggerDistance= d;}
inline G4bool GetReportSoftWarnings() const {return fReportSoftWarnings;}

Some files were not shown because too many files have changed in this diff Show More