Modify scale & offset of WhereDummyDq (#27109)
### Description
<!-- Describe your changes. -->
- Update `WhereDummyDq` QDQ transformer to be more selective before
inserting a dummy `DequantizeLinear` around `Where`.
- `SatisfyCondition` now requires the `Where` output to have exactly one
consumer and that consumer must be `QuantizeLinear` (Q). Otherwise, the
transform is skipped.
- `InsertDummyDQ` additionally checks element type consistency between
the upstream DQ input tensor type and the downstream Q output tensor
type; if they differ, the transform returns without modifying the graph.
- Update the implementation of `WhereDummyDq` to avoid negative or zero
`scale` value. The change maps the float value to the **boundary** of
integer domain to ensure the `scale` value is positive.
- If `WhereOp` get a float scalar `xf` and a `DequantizeLinear` as its
two inputs, `WhereDummyDq` insert DQ to ensure `xf = DQ(xq, scale, zp)`
- The `xq`, `scale` and `zp` are determined with the following table.
| | uint8 | uint16 | int8 | int16 |
|-----------------|--------------|---------------|-------------|---------------|
| xf > 0 | | | | |
| xq | 255 | 65535 | 127 | 32767 |
| zp | 127 | 32767 | 0 | 0 |
| xf < 0 | | | | |
| xq | 0 | 0 | -128 | -32768 |
| zp | 127 | 32767 | 0 | 0 |
| xf = 0 | | | | |
| xq | 127 | 32767 | 0 | 0 |
| zp | 127 | 32767 | 0 | 0 |
- `scale = xf / (xq - zp)` if `xq != zp` else `1`
### Motivation and Context
<!-- - Why is this change required? What problem does it solve?
- If it fixes an open issue, please link to the issue here. -->
- Negative or zero scale value is not friendly for various EP and
backend such as QNN-EP.
- Inserting an additional DQ is only useful when it forms a valid QDQ
“node unit” pattern. If the `Where` output is not followed by a single
`QuantizeLinear` (e.g., multiple consumers or a non-Q consumer), adding
a dummy DQ cannot create the intended pattern and may lead to
non-fusible/undesired graph structures.